summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/gfiledaemon.c44
-rw-r--r--client/gfiledaemonlocal.c10
-rw-r--r--client/gfileenumeratordaemon.c10
-rw-r--r--client/gfileenumeratordaemon.h2
-rw-r--r--client/gfileinputstreamdaemon.c2
-rw-r--r--client/gfileoutputstreamdaemon.c8
-rw-r--r--client/gvfsdaemondbus.c228
-rw-r--r--client/gvfsdaemondbus.h1
-rw-r--r--common/gvfsdaemonprotocol.h16
-rw-r--r--configure.ac10
-rw-r--r--daemon/gvfsbackend.h13
-rw-r--r--daemon/gvfsbackendsmb.c78
-rw-r--r--daemon/gvfsbackendsmbbrowse.c36
-rw-r--r--daemon/gvfsbackendtest.c11
-rw-r--r--daemon/gvfsdaemonprotocol.c265
-rw-r--r--daemon/gvfsjobenumerate.c43
-rw-r--r--daemon/gvfsjobenumerate.h6
-rw-r--r--daemon/gvfsjobgetinfo.c25
-rw-r--r--daemon/gvfsjobgetinfo.h5
-rw-r--r--gio/gfile.c10
-rw-r--r--gio/gfile.h16
-rw-r--r--gio/gfileenumeratorlocal.c12
-rw-r--r--gio/gfileenumeratorlocal.h4
-rw-r--r--gio/gfileinfo.c1510
-rw-r--r--gio/gfileinfo.h238
-rw-r--r--gio/gfileinfolocal.c160
-rw-r--r--gio/gfileinfolocal.h5
-rw-r--r--gio/gfileinputstream.c3
-rw-r--r--gio/gfileinputstream.h2
-rw-r--r--gio/gfileinputstreamlocal.c3
-rw-r--r--gio/gfilelocal.c13
-rw-r--r--gio/gfileoutputstream.c20
-rw-r--r--gio/gfileoutputstream.h7
-rw-r--r--gio/gfileoutputstreamlocal.c18
-rw-r--r--programs/gvfs-info.c38
-rw-r--r--programs/gvfs-ls.c12
36 files changed, 1627 insertions, 1257 deletions
diff --git a/client/gfiledaemon.c b/client/gfiledaemon.c
index e19581d7..18648128 100644
--- a/client/gfiledaemon.c
+++ b/client/gfiledaemon.c
@@ -370,16 +370,13 @@ do_async_path_call (GFile *file,
static GFileEnumerator *
g_file_daemon_enumerate_children (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error)
{
DBusMessage *reply;
- guint32 requested_32;
- dbus_bool_t follow_symlinks_dbus;
- DBusMessageIter iter;
+ dbus_uint32_t flags_dbus;
char *obj_path;
GFileEnumeratorDaemon *enumerator;
DBusConnection *connection;
@@ -387,17 +384,15 @@ g_file_daemon_enumerate_children (GFile *file,
enumerator = g_file_enumerator_daemon_new ();
obj_path = g_file_enumerator_daemon_get_object_path (enumerator);
- requested_32 = (guint32)requested;
if (attributes == NULL)
attributes = "";
- follow_symlinks_dbus = follow_symlinks;
+ flags_dbus = flags;
reply = do_sync_path_call (file,
G_VFS_DBUS_OP_ENUMERATE,
&connection, cancellable, error,
DBUS_TYPE_STRING, &obj_path,
- DBUS_TYPE_UINT32, &requested_32,
DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_BOOLEAN, &follow_symlinks_dbus,
+ DBUS_TYPE_UINT32, &flags_dbus,
0);
g_free (obj_path);
@@ -405,19 +400,9 @@ g_file_daemon_enumerate_children (GFile *file,
if (reply == NULL)
goto error;
- if (!dbus_message_iter_init (reply, &iter) ||
- (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32))
- {
- g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_IO,
- _("Invalid return value from Enumerate"));
- goto error;
- }
-
- dbus_message_iter_get_basic (&iter, &requested_32);
dbus_message_unref (reply);
g_file_enumerator_daemon_set_sync_connection (enumerator, connection);
- g_file_enumerator_daemon_set_request_flags (enumerator, requested_32);
return G_FILE_ENUMERATOR (enumerator);
@@ -430,28 +415,24 @@ g_file_daemon_enumerate_children (GFile *file,
static GFileInfo *
g_file_daemon_get_info (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error)
{
DBusMessage *reply;
- guint32 requested_32;
- dbus_bool_t follow_symlinks_dbus;
+ dbus_uint32_t flags_dbus;
DBusMessageIter iter;
GFileInfo *info;
- requested_32 = (guint32)requested;
if (attributes == NULL)
attributes = "";
- follow_symlinks_dbus = follow_symlinks;
+ flags_dbus = flags;
reply = do_sync_path_call (file,
G_VFS_DBUS_OP_GET_INFO,
NULL, cancellable, error,
- DBUS_TYPE_UINT32, &requested_32,
DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_BOOLEAN, &follow_symlinks_dbus,
+ DBUS_TYPE_UINT32, &flags,
0);
if (reply == NULL)
return NULL;
@@ -459,19 +440,14 @@ g_file_daemon_get_info (GFile *file,
info = NULL;
if (!dbus_message_iter_init (reply, &iter) ||
- (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32))
+ (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT))
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_IO,
_("Invalid return value from get_info"));
goto out;
}
- dbus_message_iter_get_basic (&iter, &requested_32);
-
- if (!dbus_message_iter_next (&iter))
- goto out;
-
- info = _g_dbus_get_file_info (&iter, requested_32, error);
+ info = _g_dbus_get_file_info (&iter, error);
out:
dbus_message_unref (reply);
diff --git a/client/gfiledaemonlocal.c b/client/gfiledaemonlocal.c
index 79152e02..d4cd5ebe 100644
--- a/client/gfiledaemonlocal.c
+++ b/client/gfiledaemonlocal.c
@@ -114,27 +114,25 @@ g_file_daemon_local_get_child (GFile *file,
static GFileEnumerator *
g_file_daemon_local_enumerate_children (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error)
{
return g_file_enumerate_children (G_FILE_DAEMON_LOCAL (file)->wrapped,
- requested, attributes, follow_symlinks,
+ attributes, flags,
cancellable, error);
}
static GFileInfo *
g_file_daemon_local_get_info (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error)
{
return g_file_get_info (G_FILE_DAEMON_LOCAL (file)->wrapped,
- requested, attributes, follow_symlinks,
+ attributes, flags,
cancellable, error);
}
diff --git a/client/gfileenumeratordaemon.c b/client/gfileenumeratordaemon.c
index 277b106e..b7505a73 100644
--- a/client/gfileenumeratordaemon.c
+++ b/client/gfileenumeratordaemon.c
@@ -22,7 +22,6 @@ struct _GFileEnumeratorDaemon
gint id;
DBusConnection *sync_connection;
- GFileInfoRequestFlags request_flags;
/* protected by infos lock */
GList *infos;
@@ -131,7 +130,7 @@ g_file_enumerator_daemon_dbus_filter (DBusConnection *connection,
while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRUCT)
{
- info = _g_dbus_get_file_info (&array_iter, enumerator->request_flags, NULL);
+ info = _g_dbus_get_file_info (&array_iter, NULL);
if (info)
g_assert (G_IS_FILE_INFO (info));
@@ -165,13 +164,6 @@ g_file_enumerator_daemon_set_sync_connection (GFileEnumeratorDaemon *enumerator,
enumerator->sync_connection = dbus_connection_ref (connection);
}
-void
-g_file_enumerator_daemon_set_request_flags (GFileEnumeratorDaemon *enumerator,
- GFileInfoRequestFlags flags)
-{
- enumerator->request_flags = flags;
-}
-
static GFileInfo *
g_file_enumerator_daemon_next_file (GFileEnumerator *enumerator,
GCancellable *cancellable,
diff --git a/client/gfileenumeratordaemon.h b/client/gfileenumeratordaemon.h
index 759f56e9..bdaeaee6 100644
--- a/client/gfileenumeratordaemon.h
+++ b/client/gfileenumeratordaemon.h
@@ -29,8 +29,6 @@ GFileEnumeratorDaemon *g_file_enumerator_daemon_new (void);
char * g_file_enumerator_daemon_get_object_path (GFileEnumeratorDaemon *enumerator);
void g_file_enumerator_daemon_set_sync_connection (GFileEnumeratorDaemon *enumerator,
DBusConnection *connection);
-void g_file_enumerator_daemon_set_request_flags (GFileEnumeratorDaemon *enumerator,
- GFileInfoRequestFlags flags);
G_END_DECLS
diff --git a/client/gfileinputstreamdaemon.c b/client/gfileinputstreamdaemon.c
index d336da4f..89805758 100644
--- a/client/gfileinputstreamdaemon.c
+++ b/client/gfileinputstreamdaemon.c
@@ -156,7 +156,6 @@ static gboolean g_file_input_stream_daemon_close (GInputStream
GCancellable *cancellable,
GError **error);
static GFileInfo *g_file_input_stream_daemon_get_file_info (GFileInputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error);
@@ -1180,7 +1179,6 @@ g_file_input_stream_daemon_seek (GFileInputStream *stream,
static GFileInfo *
g_file_input_stream_daemon_get_file_info (GFileInputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error)
diff --git a/client/gfileoutputstreamdaemon.c b/client/gfileoutputstreamdaemon.c
index 9e5c51c5..a1ea91c4 100644
--- a/client/gfileoutputstreamdaemon.c
+++ b/client/gfileoutputstreamdaemon.c
@@ -136,7 +136,6 @@ static gboolean g_file_output_stream_daemon_close (GOutputStream
GCancellable *cancellable,
GError **error);
static GFileInfo *g_file_output_stream_daemon_get_file_info (GFileOutputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error);
@@ -936,10 +935,9 @@ g_file_output_stream_daemon_seek (GFileOutputStream *stream,
static GFileInfo *
g_file_output_stream_daemon_get_file_info (GFileOutputStream *stream,
- GFileInfoRequestFlags requested,
- char *attributes,
- GCancellable *cancellable,
- GError **error)
+ char *attributes,
+ GCancellable *cancellable,
+ GError **error)
{
GFileOutputStreamDaemon *file;
diff --git a/client/gvfsdaemondbus.c b/client/gvfsdaemondbus.c
index bdeabad2..64041f12 100644
--- a/client/gvfsdaemondbus.c
+++ b/client/gvfsdaemondbus.c
@@ -901,11 +901,11 @@ _g_dbus_connection_get_sync (const char *dbus_id,
GFileInfo *
_g_dbus_get_file_info (DBusMessageIter *iter,
- GFileInfoRequestFlags requested,
GError **error)
{
GFileInfo *info;
- DBusMessageIter struct_iter, array_iter;
+ DBusMessageIter struct_iter, array_iter, inner_struct_iter, variant_iter, cstring_iter;
+ const char *attribute;
info = g_file_info_new ();
@@ -914,177 +914,73 @@ _g_dbus_get_file_info (DBusMessageIter *iter,
dbus_message_iter_recurse (iter, &struct_iter);
- if (requested & G_FILE_INFO_FILE_TYPE)
- {
- guint16 type;
-
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_UINT16)
- goto error;
-
- dbus_message_iter_get_basic (&struct_iter, &type);
-
- g_file_info_set_file_type (info, type);
-
- dbus_message_iter_next (&struct_iter);
- }
-
- if (requested & G_FILE_INFO_NAME)
- {
- char *str;
- const char *data;
- int len;
-
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type (&struct_iter) != DBUS_TYPE_BYTE)
- goto error;
-
- dbus_message_iter_recurse (&struct_iter, &array_iter);
- dbus_message_iter_get_fixed_array (&array_iter, &data, &len);
- str = g_strndup (data, len);
- g_file_info_set_name (info, str);
- g_free (str);
-
- dbus_message_iter_next (&struct_iter);
- }
-
- if (requested & G_FILE_INFO_DISPLAY_NAME)
- {
- const char *str;
-
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_STRING)
- goto error;
-
- dbus_message_iter_get_basic (&struct_iter, &str);
-
- g_file_info_set_display_name (info, str);
- dbus_message_iter_next (&struct_iter);
- }
-
- if (requested & G_FILE_INFO_EDIT_NAME)
- {
- const char *str;
-
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_STRING)
- goto error;
-
- dbus_message_iter_get_basic (&struct_iter, &str);
-
- g_file_info_set_edit_name (info, str);
- dbus_message_iter_next (&struct_iter);
- }
-
- if (requested & G_FILE_INFO_ICON)
- {
- const char *str;
-
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_STRING)
- goto error;
-
- dbus_message_iter_get_basic (&struct_iter, &str);
-
- g_file_info_set_icon (info, str);
- dbus_message_iter_next (&struct_iter);
- }
-
- if (requested & G_FILE_INFO_MIME_TYPE)
- {
- const char *str;
-
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_STRING)
- goto error;
-
- dbus_message_iter_get_basic (&struct_iter, &str);
-
- g_file_info_set_mime_type (info, str);
- dbus_message_iter_next (&struct_iter);
- }
-
- if (requested & G_FILE_INFO_SIZE)
- {
- guint64 size;
-
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_UINT64)
- goto error;
-
- dbus_message_iter_get_basic (&struct_iter, &size);
-
- g_file_info_set_size (info, size);
- dbus_message_iter_next (&struct_iter);
- }
-
- if (requested & G_FILE_INFO_MODIFICATION_TIME)
- {
- guint64 time;
-
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_UINT64)
- goto error;
-
- dbus_message_iter_get_basic (&struct_iter, &time);
-
- g_file_info_set_modification_time (info, time);
- dbus_message_iter_next (&struct_iter);
- }
-
- if (requested & G_FILE_INFO_ACCESS_RIGHTS)
- {
- guint32 rights;
-
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_UINT32)
- goto error;
-
- dbus_message_iter_get_basic (&struct_iter, &rights);
-
- g_file_info_set_access_rights (info, rights);
- dbus_message_iter_next (&struct_iter);
- }
-
- if (requested & G_FILE_INFO_STAT_INFO)
- {
- guint32 tmp;
-
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_UINT32)
- goto error;
-
- dbus_message_iter_get_basic (&struct_iter, &tmp);
-
- /* TODO: implement statinfo */
- dbus_message_iter_next (&struct_iter);
- }
+ if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_ARRAY)
+ goto error;
+
+ dbus_message_iter_recurse (&struct_iter, &array_iter);
- if (requested & G_FILE_INFO_SYMLINK_TARGET)
+ while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRUCT)
{
char *str;
- const char *data;
- int len;
-
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type (&struct_iter) != DBUS_TYPE_BYTE)
- goto error;
-
- dbus_message_iter_recurse (&struct_iter, &array_iter);
- dbus_message_iter_get_fixed_array (&array_iter, &data, &len);
- str = g_strndup (data, len);
- g_file_info_set_symlink_target (info, str);
- g_free (str);
-
- dbus_message_iter_next (&struct_iter);
- }
-
- if (requested & G_FILE_INFO_IS_HIDDEN)
- {
- dbus_bool_t is_hidden;
+ int n_elements;
+ guint32 v_uint32;
+ gint32 v_int32;
+ guint64 v_uint64;
+ gint64 v_int64;
- if (dbus_message_iter_get_arg_type (&struct_iter) != DBUS_TYPE_BOOLEAN)
- goto error;
-
- dbus_message_iter_get_basic (&struct_iter, &is_hidden);
+ dbus_message_iter_recurse (&array_iter, &inner_struct_iter);
- g_file_info_set_is_hidden (info, is_hidden);
- dbus_message_iter_next (&struct_iter);
+ if (dbus_message_iter_get_arg_type (&inner_struct_iter) != DBUS_TYPE_STRING)
+ goto error;
+
+ dbus_message_iter_get_basic (&inner_struct_iter, &attribute);
+ dbus_message_iter_next (&inner_struct_iter);
+
+ if (dbus_message_iter_get_arg_type (&inner_struct_iter) != DBUS_TYPE_VARIANT)
+ goto error;
+
+ dbus_message_iter_recurse (&inner_struct_iter, &variant_iter);
+
+ switch (dbus_message_iter_get_arg_type (&variant_iter))
+ {
+ case DBUS_TYPE_STRING:
+ dbus_message_iter_get_basic (&variant_iter, &str);
+ g_file_info_set_attribute_string (info, attribute, str);
+ break;
+ case DBUS_TYPE_ARRAY:
+ if (dbus_message_iter_get_element_type (&variant_iter) != DBUS_TYPE_BYTE)
+ goto error;
+
+ dbus_message_iter_recurse (&variant_iter, &cstring_iter);
+ dbus_message_iter_get_fixed_array (&cstring_iter,
+ &str, &n_elements);
+ str = g_strndup (str, n_elements);
+ g_file_info_set_attribute_byte_string (info, attribute, str);
+ g_free (str);
+ break;
+ case DBUS_TYPE_UINT32:
+ dbus_message_iter_get_basic (&variant_iter, &v_uint32);
+ g_file_info_set_attribute_uint32 (info, attribute, v_uint32);
+ break;
+ case DBUS_TYPE_INT32:
+ dbus_message_iter_get_basic (&variant_iter, &v_int32);
+ g_file_info_set_attribute_int32 (info, attribute, v_int32);
+ break;
+ case DBUS_TYPE_UINT64:
+ dbus_message_iter_get_basic (&variant_iter, &v_uint64);
+ g_file_info_set_attribute_uint64 (info, attribute, v_uint64);
+ break;
+ case DBUS_TYPE_INT64:
+ dbus_message_iter_get_basic (&variant_iter, &v_int64);
+ g_file_info_set_attribute_int64 (info, attribute, v_int64);
+ break;
+ default:
+ goto error;
+ }
+
+ dbus_message_iter_next (&array_iter);
}
- /* TODO: Attributes */
-
dbus_message_iter_next (iter);
return info;
diff --git a/client/gvfsdaemondbus.h b/client/gvfsdaemondbus.h
index 711e8042..2fb82452 100644
--- a/client/gvfsdaemondbus.h
+++ b/client/gvfsdaemondbus.h
@@ -39,7 +39,6 @@ DBusMessage *_g_vfs_daemon_call_sync (DBusMessage
GCancellable *cancellable,
GError **error);
GFileInfo * _g_dbus_get_file_info (DBusMessageIter *iter,
- GFileInfoRequestFlags requested,
GError **error);
diff --git a/common/gvfsdaemonprotocol.h b/common/gvfsdaemonprotocol.h
index 24f43cb0..e085e49e 100644
--- a/common/gvfsdaemonprotocol.h
+++ b/common/gvfsdaemonprotocol.h
@@ -83,9 +83,21 @@ typedef struct {
#define G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_WRITTEN 3
#define G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_CLOSED 4
-char *g_dbus_get_file_info_signature (GFileInfoRequestFlags requested);
+#define G_FILE_INFO_INNER_TYPE_AS_STRING \
+ DBUS_TYPE_ARRAY_AS_STRING \
+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING \
+ DBUS_TYPE_STRING_AS_STRING \
+ DBUS_TYPE_VARIANT_AS_STRING \
+ DBUS_STRUCT_END_CHAR_AS_STRING
+
+#define G_FILE_INFO_TYPE_AS_STRING \
+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING \
+ G_FILE_INFO_INNER_TYPE_AS_STRING \
+ DBUS_STRUCT_END_CHAR_AS_STRING
+
+
+char *g_dbus_get_file_info_signature (void);
void g_dbus_append_file_info (DBusMessageIter *iter,
- GFileInfoRequestFlags requested,
GFileInfo *file_info);
G_END_DECLS
diff --git a/configure.ac b/configure.ac
index fec7e588..d63a22e9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,6 +22,16 @@ AC_TYPE_SIGNAL
AC_TYPE_SIZE_T
AC_TYPE_UID_T
+AH_VERBATIM([_GNU_SOURCE],
+[/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif])
+
+saved_CFLAGS=$CFLAGS
+AC_CHECK_MEMBERS([struct stat.st_mtimensec, struct stat.st_mtim.tv_nsec, struct stat.st_atimensec, struct stat.st_atim.tv_nsec, struct stat.st_ctimensec, struct stat.st_ctim.tv_nsec])
+CFLAGS=$saved_CFLAGS
+
GTK_DOC_CHECK
DISTCHECK_CONFIGURE_FLAGS="--enable-gtk-doc"
AC_SUBST(DISTCHECK_CONFIGURE_FLAGS)
diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h
index cd5ab4d1..58a81052 100644
--- a/daemon/gvfsbackend.h
+++ b/daemon/gvfsbackend.h
@@ -4,6 +4,7 @@
#include <dbus/dbus.h>
#include <gio/gvfstypes.h>
#include <gio/gfileinfo.h>
+#include <gio/gfile.h>
#include <gvfsdaemon.h>
#include <gvfsjob.h>
#include <gmountspec.h>
@@ -148,27 +149,23 @@ struct _GVfsBackendClass
void (*get_info) (GVfsBackend *backend,
GVfsJobGetInfo *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks);
+ GFileGetInfoFlags flags);
gboolean (*try_get_info) (GVfsBackend *backend,
GVfsJobGetInfo *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks);
+ GFileGetInfoFlags flags);
void (*enumerate) (GVfsBackend *backend,
GVfsJobEnumerate *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks);
+ GFileGetInfoFlags flags);
gboolean (*try_enumerate) (GVfsBackend *backend,
GVfsJobEnumerate *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks);
+ GFileGetInfoFlags flags);
};
GType g_vfs_backend_get_type (void) G_GNUC_CONST;
diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c
index 3ead85ec..c94f72ee 100644
--- a/daemon/gvfsbackendsmb.c
+++ b/daemon/gvfsbackendsmb.c
@@ -1075,15 +1075,73 @@ do_close_write (GVfsBackend *backend,
}
static void
+set_info_from_stat (GFileInfo *info, struct stat *statbuf)
+{
+ GFileType file_type;
+ GTimeVal t;
+
+ file_type = G_FILE_TYPE_UNKNOWN;
+
+ if (S_ISREG (statbuf->st_mode))
+ file_type = G_FILE_TYPE_REGULAR;
+ else if (S_ISDIR (statbuf->st_mode))
+ file_type = G_FILE_TYPE_DIRECTORY;
+ else if (S_ISCHR (statbuf->st_mode) ||
+ S_ISBLK (statbuf->st_mode) ||
+ S_ISFIFO (statbuf->st_mode)
+#ifdef S_ISSOCK
+ || S_ISSOCK (statbuf->st_mode)
+#endif
+ )
+ file_type = G_FILE_TYPE_SPECIAL;
+ else if (S_ISLNK (statbuf->st_mode))
+ file_type = G_FILE_TYPE_SYMBOLIC_LINK;
+
+ g_file_info_set_file_type (info, file_type);
+ g_file_info_set_size (info, statbuf->st_size);
+
+ t.tv_sec = statbuf->st_mtime;
+#if defined (HAVE_STRUCT_STAT_ST_MTIMENSEC)
+ t.tv_usec = statbuf->st_mtimensec / 1000;
+#elif defined (HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+ t.tv_usec = statbuf->st_mtim.tv_nsec / 1000;
+#else
+ t.tv_usec = 0;
+#endif
+ g_file_info_set_modification_time (info, &t);
+
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_DEVICE, statbuf->st_dev);
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_INODE, statbuf->st_ino);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE, statbuf->st_mode);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_NLINK, statbuf->st_nlink);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID, statbuf->st_uid);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID, statbuf->st_uid);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_RDEV, statbuf->st_rdev);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_BLOCK_SIZE, statbuf->st_blksize);
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_BLOCKS, statbuf->st_blocks);
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_ATIME, statbuf->st_atime);
+#if defined (HAVE_STRUCT_STAT_ST_ATIMENSEC)
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_ATIME_USEC, statbuf->st_atimensec / 1000);
+#elif defined (HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC)
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_ATIME_USEC, statbuf->st_atim.tv_nsec / 1000);
+#endif
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_CTIME, statbuf->st_ctime);
+#if defined (HAVE_STRUCT_STAT_ST_CTIMENSEC)
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_CTIME_USEC, statbuf->st_ctimensec / 1000);
+#elif defined (HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC)
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_CTIME_USEC, statbuf->st_ctim.tv_nsec / 1000);
+#endif
+}
+
+static void
do_get_info (GVfsBackend *backend,
GVfsJobGetInfo *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks)
+ GFileGetInfoFlags flags)
{
GVfsBackendSmb *op_backend = G_VFS_BACKEND_SMB (backend);
- struct stat st;
+ struct stat st = {0};
char *uri;
int res;
GFileInfo *info;
@@ -1095,9 +1153,9 @@ do_get_info (GVfsBackend *backend,
if (res == 0)
{
info = g_file_info_new ();
- g_file_info_set_from_stat (info, requested, &st);
+ set_info_from_stat (info, &st);
- g_vfs_job_get_info_set_info (job, requested & ~(G_FILE_INFO_DISPLAY_NAME|G_FILE_INFO_EDIT_NAME), info);
+ g_vfs_job_get_info_set_info (job, info);
g_vfs_job_succeeded (G_VFS_JOB (job));
g_object_unref (info);
}
@@ -1109,9 +1167,8 @@ static void
do_enumerate (GVfsBackend *backend,
GVfsJobEnumerate *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks)
+ GFileGetInfoFlags flags)
{
GVfsBackendSmb *op_backend = G_VFS_BACKEND_SMB (backend);
struct stat st;
@@ -1137,8 +1194,6 @@ do_enumerate (GVfsBackend *backend,
goto error;
}
- /* TODO: limit requested to what we support */
- g_vfs_job_enumerate_set_result (job, requested);
g_vfs_job_succeeded (G_VFS_JOB (job));
if (uri->str[uri->len - 1] != '/')
@@ -1177,10 +1232,9 @@ do_enumerate (GVfsBackend *backend,
if (stat_res == 0)
{
info = g_file_info_new ();
- if (requested & G_FILE_INFO_NAME)
- g_file_info_set_name (info, dirp->name);
+ g_file_info_set_name (info, dirp->name);
- g_file_info_set_from_stat (info, requested, &st);
+ set_info_from_stat (info, &st);
files = g_list_prepend (files, info);
}
}
diff --git a/daemon/gvfsbackendsmbbrowse.c b/daemon/gvfsbackendsmbbrowse.c
index 68efba2f..ab8a493e 100644
--- a/daemon/gvfsbackendsmbbrowse.c
+++ b/daemon/gvfsbackendsmbbrowse.c
@@ -694,7 +694,6 @@ static void
run_get_info (GVfsBackendSmbBrowse *backend,
GVfsJobGetInfo *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes)
{
GFileInfo *info;
@@ -710,14 +709,15 @@ run_get_info (GVfsBackendSmbBrowse *backend,
info = g_file_info_new ();
g_file_info_set_file_type (info, G_FILE_TYPE_MOUNTABLE);
g_file_info_set_name (info, entry->name);
- g_file_info_set_attribute (info, "smb:comment", entry->comment);
+ /* TODO: Is this always UTF8? */
+ g_file_info_set_attribute_string (info, "smb:comment", entry->comment);
}
g_mutex_unlock (backend->entries_lock);
if (info)
{
- g_vfs_job_get_info_set_info (job, requested & ~(G_FILE_INFO_DISPLAY_NAME|G_FILE_INFO_EDIT_NAME), info);
+ g_vfs_job_get_info_set_info (job, info);
g_vfs_job_succeeded (G_VFS_JOB (job));
g_object_unref (info);
}
@@ -733,15 +733,14 @@ static void
do_get_info (GVfsBackend *backend,
GVfsJobGetInfo *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks)
+ GFileGetInfoFlags flags)
{
GVfsBackendSmbBrowse *op_backend = G_VFS_BACKEND_SMB_BROWSE (backend);
update_cache (op_backend);
- run_get_info (op_backend, job, filename, requested, attributes);
+ run_get_info (op_backend, job, filename, attributes);
}
@@ -749,9 +748,8 @@ static gboolean
try_get_info (GVfsBackend *backend,
GVfsJobGetInfo *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks)
+ GFileGetInfoFlags flags)
{
GVfsBackendSmbBrowse *op_backend = G_VFS_BACKEND_SMB_BROWSE (backend);
@@ -760,7 +758,7 @@ try_get_info (GVfsBackend *backend,
GFileInfo *info = g_file_info_new ();
g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
g_file_info_set_name (info, "/");
- g_vfs_job_get_info_set_info (job, requested & ~(G_FILE_INFO_DISPLAY_NAME|G_FILE_INFO_EDIT_NAME), info);
+ g_vfs_job_get_info_set_info (job, info);
g_vfs_job_succeeded (G_VFS_JOB (job));
g_object_unref (info);
@@ -770,7 +768,7 @@ try_get_info (GVfsBackend *backend,
if (cache_needs_updating (op_backend))
return FALSE;
- run_get_info (op_backend, job, filename, requested, attributes);
+ run_get_info (op_backend, job, filename, attributes);
return TRUE;
}
@@ -779,7 +777,6 @@ static void
run_enumerate (GVfsBackendSmbBrowse *backend,
GVfsJobEnumerate *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes)
{
GList *files, *l;
@@ -799,7 +796,6 @@ run_enumerate (GVfsBackendSmbBrowse *backend,
}
/* TODO: limit requested to what we support */
- g_vfs_job_enumerate_set_result (job, requested);
g_vfs_job_succeeded (G_VFS_JOB (job));
files = NULL;
@@ -810,9 +806,9 @@ run_enumerate (GVfsBackendSmbBrowse *backend,
info = g_file_info_new ();
g_file_info_set_file_type (info, G_FILE_TYPE_MOUNTABLE);
- if (requested & G_FILE_INFO_NAME)
- g_file_info_set_name (info, entry->name);
- g_file_info_set_attribute (info, "smb:comment", entry->comment);
+ g_file_info_set_name (info, entry->name);
+ /* TODO: Is this always in utf8??? */
+ g_file_info_set_attribute_string (info, "smb:comment", entry->comment);
files = g_list_prepend (files, info);
}
@@ -831,31 +827,29 @@ static void
do_enumerate (GVfsBackend *backend,
GVfsJobEnumerate *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks)
+ GFileGetInfoFlags flags)
{
GVfsBackendSmbBrowse *op_backend = G_VFS_BACKEND_SMB_BROWSE (backend);
update_cache (op_backend);
- run_enumerate (op_backend, job, filename, requested, attributes);
+ run_enumerate (op_backend, job, filename, attributes);
}
static gboolean
try_enumerate (GVfsBackend *backend,
GVfsJobEnumerate *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks)
+ GFileGetInfoFlags flags)
{
GVfsBackendSmbBrowse *op_backend = G_VFS_BACKEND_SMB_BROWSE (backend);
if (cache_needs_updating (op_backend))
return FALSE;
- run_enumerate (op_backend, job, filename, requested, attributes);
+ run_enumerate (op_backend, job, filename, attributes);
return TRUE;
}
diff --git a/daemon/gvfsbackendtest.c b/daemon/gvfsbackendtest.c
index a6088736..a8df65ed 100644
--- a/daemon/gvfsbackendtest.c
+++ b/daemon/gvfsbackendtest.c
@@ -245,9 +245,8 @@ static void
do_get_info (GVfsBackend *backend,
GVfsJobGetInfo *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks)
+ GFileGetInfoFlags flags)
{
GFile *file;
GFileInfo *info;
@@ -258,12 +257,12 @@ do_get_info (GVfsBackend *backend,
file = g_file_local_new (filename);
error = NULL;
- info = g_file_get_info (file, requested, attributes, follow_symlinks,
+ info = g_file_get_info (file, attributes, flags,
NULL, &error);
if (info)
{
- g_vfs_job_get_info_set_info (job, requested, info);
+ g_vfs_job_get_info_set_info (job, info);
g_vfs_job_succeeded (G_VFS_JOB (job));
}
else
@@ -277,16 +276,14 @@ static gboolean
try_enumerate (GVfsBackend *backend,
GVfsJobEnumerate *job,
const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks)
+ GFileGetInfoFlags flags)
{
GFileInfo *info1, *info2;;
GList *l;
g_print ("try_enumerate (%s)\n", filename);
- g_vfs_job_enumerate_set_result (job, requested);
g_vfs_job_succeeded (G_VFS_JOB (job));
info1 = g_file_info_new ();
diff --git a/daemon/gvfsdaemonprotocol.c b/daemon/gvfsdaemonprotocol.c
index 3058b670..e1b24c3b 100644
--- a/daemon/gvfsdaemonprotocol.c
+++ b/daemon/gvfsdaemonprotocol.c
@@ -3,207 +3,122 @@
#include <gvfsdaemonprotocol.h>
#include <gdbusutils.h>
-char *
-g_dbus_get_file_info_signature (GFileInfoRequestFlags requested)
-{
- GString *str;
-
- str = g_string_new (DBUS_STRUCT_BEGIN_CHAR_AS_STRING);
-
-
- if (requested & G_FILE_INFO_FILE_TYPE)
- {
- g_string_append_c (str, DBUS_TYPE_UINT16);
- }
-
- if (requested & G_FILE_INFO_NAME)
- {
- g_string_append (str, DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING);
- }
-
- if (requested & G_FILE_INFO_DISPLAY_NAME)
- {
- g_string_append_c (str, DBUS_TYPE_STRING);
- }
-
- if (requested & G_FILE_INFO_EDIT_NAME)
- {
- g_string_append_c (str, DBUS_TYPE_STRING);
- }
-
- if (requested & G_FILE_INFO_ICON)
- {
- g_string_append_c (str, DBUS_TYPE_STRING);
- }
-
- if (requested & G_FILE_INFO_MIME_TYPE)
- {
- g_string_append_c (str, DBUS_TYPE_STRING);
- }
-
- if (requested & G_FILE_INFO_SIZE)
- {
- g_string_append_c (str, DBUS_TYPE_UINT64);
- }
-
- if (requested & G_FILE_INFO_MODIFICATION_TIME)
- {
- g_string_append_c (str, DBUS_TYPE_UINT64);
- }
-
- if (requested & G_FILE_INFO_ACCESS_RIGHTS)
- {
- g_string_append_c (str, DBUS_TYPE_UINT32);
- }
-
- if (requested & G_FILE_INFO_STAT_INFO)
- {
- g_string_append_c (str, DBUS_TYPE_UINT32); /* TODO: struct */
- }
-
- if (requested & G_FILE_INFO_SYMLINK_TARGET)
- {
- g_string_append (str, DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING);
- }
-
- if (requested & G_FILE_INFO_IS_HIDDEN)
- {
- g_string_append_c (str, DBUS_TYPE_BOOLEAN);
- }
-
-
- /* TODO: Attributes */
-
- g_string_append_c (str, DBUS_STRUCT_END_CHAR);
-
- return g_string_free (str, FALSE);
-}
-
void
g_dbus_append_file_info (DBusMessageIter *iter,
- GFileInfoRequestFlags requested,
GFileInfo *info)
{
- DBusMessageIter struct_iter;
- char *sig;
+ DBusMessageIter struct_iter, variant_iter, array_iter, inner_struct_iter;
+ char **attributes;
+ int i;
+
+ attributes = g_file_info_list_attributes (info, NULL);
- sig = g_dbus_get_file_info_signature (requested);
if (!dbus_message_iter_open_container (iter,
DBUS_TYPE_STRUCT,
- sig,
+ G_FILE_INFO_INNER_TYPE_AS_STRING,
&struct_iter))
_g_dbus_oom ();
- g_free (sig);
- if (requested & G_FILE_INFO_FILE_TYPE)
- {
- guint16 type = g_file_info_get_file_type (info);
- if (!dbus_message_iter_append_basic (&struct_iter,
- DBUS_TYPE_UINT16,
- &type))
- _g_dbus_oom ();
- }
- if (requested & G_FILE_INFO_NAME)
- {
- _g_dbus_message_iter_append_cstring (&struct_iter,
- g_file_info_get_name (info));
- }
+ if (!dbus_message_iter_open_container (&struct_iter,
+ DBUS_TYPE_ARRAY,
+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_STRUCT_END_CHAR_AS_STRING,
+ &array_iter))
+ _g_dbus_oom ();
- if (requested & G_FILE_INFO_DISPLAY_NAME)
- {
- const char *str = g_file_info_get_display_name (info);
-
- if (!dbus_message_iter_append_basic (&struct_iter,
- DBUS_TYPE_STRING,
- &str))
+ for (i = 0; attributes[i] != NULL; i++)
+ {
+ GFileAttributeType type;
+ char *dbus_type;
+ void *value;
+ const char *str;
+ guint32 v_uint32;
+ gint32 v_int32;
+ guint64 v_uint64;
+ gint64 v_int64;
+
+ type = g_file_info_get_attribute_type (info, attributes[i]);
+ switch (type)
+ {
+ case G_FILE_ATTRIBUTE_TYPE_STRING:
+ dbus_type = DBUS_TYPE_STRING_AS_STRING;
+ str = g_file_info_get_attribute_string (info, attributes[i]);
+ value = &str;
+ break;
+ case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
+ dbus_type = DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
+ str = g_file_info_get_attribute_byte_string (info, attributes[i]);
+ value = &str;
+ break;
+ case G_FILE_ATTRIBUTE_TYPE_UINT32:
+ dbus_type = DBUS_TYPE_UINT32_AS_STRING;
+ v_uint32 = g_file_info_get_attribute_uint32 (info, attributes[i]);
+ value = &v_uint32;
+ break;
+ case G_FILE_ATTRIBUTE_TYPE_INT32:
+ dbus_type = DBUS_TYPE_INT32_AS_STRING;
+ v_int32 = g_file_info_get_attribute_int32 (info, attributes[i]);
+ value = &v_int32;
+ break;
+ case G_FILE_ATTRIBUTE_TYPE_UINT64:
+ dbus_type = DBUS_TYPE_UINT64_AS_STRING;
+ v_uint64 = g_file_info_get_attribute_uint64 (info, attributes[i]);
+ value = &v_uint64;
+ break;
+ case G_FILE_ATTRIBUTE_TYPE_INT64:
+ dbus_type = DBUS_TYPE_INT64_AS_STRING;
+ v_int64 = g_file_info_get_attribute_int64 (info, attributes[i]);
+ value = &v_int64;
+ break;
+ default:
+ g_warning ("Invalid attribute type %s=%d, ignoring\n", attributes[i], type);
+ continue;
+ }
+
+ if (!dbus_message_iter_open_container (&array_iter,
+ DBUS_TYPE_STRUCT,
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING,
+ &inner_struct_iter))
_g_dbus_oom ();
- }
- if (requested & G_FILE_INFO_EDIT_NAME)
- {
- const char *str = g_file_info_get_edit_name (info);
-
- if (!dbus_message_iter_append_basic (&struct_iter,
- DBUS_TYPE_STRING,
- &str))
- _g_dbus_oom ();
- }
- if (requested & G_FILE_INFO_ICON)
- {
- const char *str = g_file_info_get_icon (info);
-
- if (!dbus_message_iter_append_basic (&struct_iter,
+ if (!dbus_message_iter_append_basic (&inner_struct_iter,
DBUS_TYPE_STRING,
- &str))
+ &attributes[i]))
_g_dbus_oom ();
- }
- if (requested & G_FILE_INFO_MIME_TYPE)
- {
- const char *str = g_file_info_get_mime_type (info);
-
- if (!dbus_message_iter_append_basic (&struct_iter,
- DBUS_TYPE_STRING,
- &str))
- _g_dbus_oom ();
- }
- if (requested & G_FILE_INFO_SIZE)
- {
- guint64 size = g_file_info_get_size (info);
- if (!dbus_message_iter_append_basic (&struct_iter,
- DBUS_TYPE_UINT64,
- &size))
- _g_dbus_oom ();
- }
-
- if (requested & G_FILE_INFO_MODIFICATION_TIME)
- {
- guint64 time = g_file_info_get_modification_time (info);
- if (!dbus_message_iter_append_basic (&struct_iter,
- DBUS_TYPE_UINT64,
- &time))
+ if (!dbus_message_iter_open_container (&inner_struct_iter,
+ DBUS_TYPE_VARIANT,
+ dbus_type,
+ &variant_iter))
_g_dbus_oom ();
- }
- if (requested & G_FILE_INFO_ACCESS_RIGHTS)
- {
- guint32 rights = g_file_info_get_access_rights (info);
- if (!dbus_message_iter_append_basic (&struct_iter,
- DBUS_TYPE_UINT32,
- &rights))
- _g_dbus_oom ();
- }
-
- if (requested & G_FILE_INFO_STAT_INFO)
- {
- /* TODO: implement statinfo */
- guint32 tmp = 0;
- if (!dbus_message_iter_append_basic (&struct_iter,
- DBUS_TYPE_UINT32,
- &tmp))
+ if (dbus_type[0] == DBUS_TYPE_ARRAY)
+ _g_dbus_message_iter_append_cstring (&variant_iter, *(char **)value);
+ else
+ {
+ if (!dbus_message_iter_append_basic (&variant_iter,
+ dbus_type[0], value))
+ _g_dbus_oom ();
+ }
+
+ if (!dbus_message_iter_close_container (&inner_struct_iter, &variant_iter))
_g_dbus_oom ();
- }
-
- if (requested & G_FILE_INFO_SYMLINK_TARGET)
- {
- _g_dbus_message_iter_append_cstring (&struct_iter,
- g_file_info_get_symlink_target (info));
- }
-
- if (requested & G_FILE_INFO_IS_HIDDEN)
- {
- dbus_bool_t is_hidden = g_file_info_get_is_hidden (info);
- if (!dbus_message_iter_append_basic (&struct_iter,
- DBUS_TYPE_BOOLEAN,
- &is_hidden))
+
+ if (!dbus_message_iter_close_container (&array_iter, &inner_struct_iter))
_g_dbus_oom ();
}
- /* TODO: Attributes */
+ g_strfreev (attributes);
+ if (!dbus_message_iter_close_container (&struct_iter, &array_iter))
+ _g_dbus_oom ();
+
if (!dbus_message_iter_close_container (iter, &struct_iter))
_g_dbus_oom ();
}
diff --git a/daemon/gvfsjobenumerate.c b/daemon/gvfsjobenumerate.c
index f2976dbd..5090eb1c 100644
--- a/daemon/gvfsjobenumerate.c
+++ b/daemon/gvfsjobenumerate.c
@@ -66,18 +66,16 @@ g_vfs_job_enumerate_new (DBusConnection *connection,
int path_len;
const char *obj_path;
const char *path_data;
- guint32 requested;
char *attributes;
- dbus_bool_t follow_symlinks;
+ dbus_uint32_t flags;
dbus_error_init (&derror);
if (!dbus_message_get_args (message, &derror,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
&path_data, &path_len,
DBUS_TYPE_STRING, &obj_path,
- DBUS_TYPE_UINT32, &requested,
DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_BOOLEAN, &follow_symlinks,
+ DBUS_TYPE_UINT32, &flags,
0))
{
reply = dbus_message_new_error (message,
@@ -97,28 +95,18 @@ g_vfs_job_enumerate_new (DBusConnection *connection,
job->object_path = g_strdup (obj_path);
job->filename = g_strndup (path_data, path_len);
job->backend = backend;
- job->requested = requested;
job->attributes = g_strdup (attributes);
- job->follow_symlinks = follow_symlinks;
+ job->flags = flags;
return G_VFS_JOB (job);
}
-
-void
-g_vfs_job_enumerate_set_result (GVfsJobEnumerate *job,
- GFileInfoRequestFlags requested_result)
-{
- job->requested_result = requested_result;
-}
-
void
g_vfs_job_enumerate_add_info (GVfsJobEnumerate *job,
GList *infos)
{
DBusMessage *message, *orig_message;
DBusMessageIter iter, array_iter;
- char *sig;
int num;
restart:
@@ -133,20 +121,16 @@ g_vfs_job_enumerate_add_info (GVfsJobEnumerate *job,
dbus_message_iter_init_append (message, &iter);
- sig = g_dbus_get_file_info_signature (job->requested_result);
-
if (!dbus_message_iter_open_container (&iter,
- DBUS_TYPE_ARRAY, sig,
+ DBUS_TYPE_ARRAY,
+ G_FILE_INFO_TYPE_AS_STRING,
&array_iter))
_g_dbus_oom ();
- g_free (sig);
-
num = 0;
while (infos != NULL)
{
g_dbus_append_file_info (&array_iter,
- job->requested_result,
infos->data);
infos = infos->next;
if (++num > 100)
@@ -195,9 +179,8 @@ run (GVfsJob *job)
class->enumerate (op_job->backend,
op_job,
op_job->filename,
- op_job->requested,
op_job->attributes,
- op_job->follow_symlinks);
+ op_job->flags);
}
static gboolean
@@ -212,9 +195,8 @@ try (GVfsJob *job)
return class->try_enumerate (op_job->backend,
op_job,
op_job->filename,
- op_job->requested,
op_job->attributes,
- op_job->follow_symlinks);
+ op_job->flags);
}
static void
@@ -249,20 +231,9 @@ create_reply (GVfsJob *job,
DBusConnection *connection,
DBusMessage *message)
{
- GVfsJobEnumerate *op_job = G_VFS_JOB_ENUMERATE (job);
DBusMessage *reply;
- DBusMessageIter iter;
- guint32 requested_32;
reply = dbus_message_new_method_return (message);
- dbus_message_iter_init_append (reply, &iter);
-
- requested_32 = op_job->requested_result;
- if (!dbus_message_iter_append_basic (&iter,
- DBUS_TYPE_UINT32,
- &requested_32))
- _g_dbus_oom ();
-
return reply;
}
diff --git a/daemon/gvfsjobenumerate.h b/daemon/gvfsjobenumerate.h
index 360c1549..7080bac2 100644
--- a/daemon/gvfsjobenumerate.h
+++ b/daemon/gvfsjobenumerate.h
@@ -24,11 +24,9 @@ struct _GVfsJobEnumerate
GVfsBackend *backend;
char *filename;
char *object_path;
- GFileInfoRequestFlags requested;
char *attributes;
- gboolean follow_symlinks;
+ GFileGetInfoFlags flags;
- GFileInfoRequestFlags requested_result;
};
struct _GVfsJobEnumerateClass
@@ -41,8 +39,6 @@ GType g_vfs_job_enumerate_get_type (void) G_GNUC_CONST;
GVfsJob *g_vfs_job_enumerate_new (DBusConnection *connection,
DBusMessage *message,
GVfsBackend *backend);
-void g_vfs_job_enumerate_set_result (GVfsJobEnumerate *job,
- GFileInfoRequestFlags requested_result);
void g_vfs_job_enumerate_add_info (GVfsJobEnumerate *job,
GList *info);
void g_vfs_job_enumerate_done (GVfsJobEnumerate *job);
diff --git a/daemon/gvfsjobgetinfo.c b/daemon/gvfsjobgetinfo.c
index 57db3cce..64aae474 100644
--- a/daemon/gvfsjobgetinfo.c
+++ b/daemon/gvfsjobgetinfo.c
@@ -65,17 +65,15 @@ g_vfs_job_get_info_new (DBusConnection *connection,
DBusError derror;
int path_len;
const char *path_data;
- guint32 requested;
char *attributes;
- dbus_bool_t follow_symlinks;
+ dbus_uint32_t flags;
dbus_error_init (&derror);
if (!dbus_message_get_args (message, &derror,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
&path_data, &path_len,
- DBUS_TYPE_UINT32, &requested,
DBUS_TYPE_STRING, &attributes,
- DBUS_TYPE_BOOLEAN, &follow_symlinks,
+ DBUS_TYPE_UINT32, &flags,
0))
{
reply = dbus_message_new_error (message,
@@ -94,9 +92,8 @@ g_vfs_job_get_info_new (DBusConnection *connection,
job->filename = g_strndup (path_data, path_len);
job->backend = backend;
- job->requested = requested;
job->attributes = g_strdup (attributes);
- job->follow_symlinks = follow_symlinks;
+ job->flags = flags;
return G_VFS_JOB (job);
}
@@ -110,9 +107,8 @@ run (GVfsJob *job)
class->get_info (op_job->backend,
op_job,
op_job->filename,
- op_job->requested,
op_job->attributes,
- op_job->follow_symlinks);
+ op_job->flags);
}
static gboolean
@@ -127,17 +123,14 @@ try (GVfsJob *job)
return class->try_get_info (op_job->backend,
op_job,
op_job->filename,
- op_job->requested,
op_job->attributes,
- op_job->follow_symlinks);
+ op_job->flags);
}
void
g_vfs_job_get_info_set_info (GVfsJobGetInfo *job,
- GFileInfoRequestFlags requested_result,
GFileInfo *file_info)
{
- job->requested_result = requested_result;
job->file_info = g_object_ref (file_info);
}
@@ -150,20 +143,12 @@ create_reply (GVfsJob *job,
GVfsJobGetInfo *op_job = G_VFS_JOB_GET_INFO (job);
DBusMessage *reply;
DBusMessageIter iter;
- guint32 requested_32;
reply = dbus_message_new_method_return (message);
dbus_message_iter_init_append (reply, &iter);
- requested_32 = op_job->requested_result;
- if (!dbus_message_iter_append_basic (&iter,
- DBUS_TYPE_UINT32,
- &requested_32))
- _g_dbus_oom ();
-
g_dbus_append_file_info (&iter,
- op_job->requested_result,
op_job->file_info);
return reply;
diff --git a/daemon/gvfsjobgetinfo.h b/daemon/gvfsjobgetinfo.h
index 9d1df88b..0d0636f1 100644
--- a/daemon/gvfsjobgetinfo.h
+++ b/daemon/gvfsjobgetinfo.h
@@ -23,11 +23,9 @@ struct _GVfsJobGetInfo
GVfsBackend *backend;
char *filename;
- GFileInfoRequestFlags requested;
char *attributes;
- gboolean follow_symlinks;
+ GFileGetInfoFlags flags;
- GFileInfoRequestFlags requested_result;
GFileInfo *file_info;
};
@@ -42,7 +40,6 @@ GVfsJob *g_vfs_job_get_info_new (DBusConnection *connection,
DBusMessage *message,
GVfsBackend *backend);
void g_vfs_job_get_info_set_info (GVfsJobGetInfo *job,
- GFileInfoRequestFlags requested_result,
GFileInfo *file_info);
G_END_DECLS
diff --git a/gio/gfile.c b/gio/gfile.c
index 1fbb52fb..13ccef6b 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -137,9 +137,8 @@ g_file_get_child (GFile *file,
GFileEnumerator *
g_file_enumerate_children (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error)
@@ -148,15 +147,14 @@ g_file_enumerate_children (GFile *file,
iface = G_FILE_GET_IFACE (file);
- return (* iface->enumerate_children) (file, requested, attributes, follow_symlinks,
+ return (* iface->enumerate_children) (file, attributes, flags,
cancellable, error);
}
GFileInfo *
g_file_get_info (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error)
{
@@ -164,7 +162,7 @@ g_file_get_info (GFile *file,
iface = G_FILE_GET_IFACE (file);
- return (* iface->get_info) (file, requested, attributes, follow_symlinks, cancellable, error);
+ return (* iface->get_info) (file, attributes, flags, cancellable, error);
}
GFileInputStream *
diff --git a/gio/gfile.h b/gio/gfile.h
index 66593e5a..7e065979 100644
--- a/gio/gfile.h
+++ b/gio/gfile.h
@@ -15,6 +15,10 @@ G_BEGIN_DECLS
#define G_IS_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_FILE))
#define G_FILE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_FILE, GFileIface))
+typedef enum {
+ G_FILE_GET_INFO_NOFOLLOW_SYMLINKS = (1<<0)
+} GFileGetInfoFlags;
+
typedef struct _GFile GFile; /* Dummy typedef */
typedef struct _GFileIface GFileIface;
@@ -39,15 +43,13 @@ struct _GFileIface
GFile * (*get_child) (GFile *file,
const char *name);
GFileEnumerator * (*enumerate_children) (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error);
GFileInfo * (*get_info) (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error);
/* (*get_info_async) (GFile *file.. */
@@ -93,15 +95,13 @@ GFile * g_file_get_parent (GFile *file);
GFile * g_file_get_child (GFile *file,
const char *name);
GFileEnumerator * g_file_enumerate_children (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error);
GFileInfo * g_file_get_info (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error);
GFileInputStream * g_file_read (GFile *file,
diff --git a/gio/gfileenumeratorlocal.c b/gio/gfileenumeratorlocal.c
index 04d8d811..0acb4727 100644
--- a/gio/gfileenumeratorlocal.c
+++ b/gio/gfileenumeratorlocal.c
@@ -19,8 +19,9 @@ struct _GFileEnumeratorLocal
GFileAttributeMatcher *matcher;
GDir *dir;
char *filename;
- GFileInfoRequestFlags requested;
char *attributes;
+ GFileGetInfoFlags flags;
+
gboolean follow_symlinks;
};
@@ -73,9 +74,8 @@ g_file_enumerator_local_init (GFileEnumeratorLocal *local)
GFileEnumerator *
g_file_enumerator_local_new (const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error)
{
@@ -90,9 +90,8 @@ g_file_enumerator_local_new (const char *filename,
local->dir = dir;
local->filename = g_strdup (filename);
- local->requested = requested;
local->matcher = g_file_attribute_matcher_new (attributes);
- local->follow_symlinks = follow_symlinks;
+ local->flags = flags;
return G_FILE_ENUMERATOR (local);
}
@@ -116,9 +115,8 @@ g_file_enumerator_local_next_file (GFileEnumerator *enumerator,
path = g_build_filename (local->filename, filename, NULL);
info = g_file_info_local_get (filename, path,
- local->requested,
local->matcher,
- local->follow_symlinks,
+ local->flags,
&my_error);
g_free (path);
diff --git a/gio/gfileenumeratorlocal.h b/gio/gfileenumeratorlocal.h
index 4bf8051b..c7a8d117 100644
--- a/gio/gfileenumeratorlocal.h
+++ b/gio/gfileenumeratorlocal.h
@@ -3,6 +3,7 @@
#include <gfileenumerator.h>
#include <gfileinfo.h>
+#include <gfile.h>
G_BEGIN_DECLS
@@ -27,9 +28,8 @@ struct _GFileEnumeratorLocalClass
GType g_file_enumerator_local_get_type (void) G_GNUC_CONST;
GFileEnumerator *g_file_enumerator_local_new (const char *filename,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error);
diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c
index 4a39da57..ee475aa1 100644
--- a/gio/gfileinfo.c
+++ b/gio/gfileinfo.c
@@ -6,58 +6,178 @@
#include "gfileinfo.h"
#include <glib/gi18n-lib.h>
-G_DEFINE_TYPE (GFileInfo, g_file_info, G_TYPE_OBJECT);
-
typedef struct {
- GQuark namespace_q;
- GQuark attribute_q; /* full namespace:attribute form */
- char *value;
-} GFileAttributeInternal;
-
-
-struct _GFileInfoPrivate {
- GFileType file_type;
- char *name;
- char *display_name;
- char *edit_name;
- char *icon;
- GQuark mime_type_q;
- goffset size;
- time_t mtime;
- GFileAccessRights access_rights;
- struct stat *stat_info;
- char *symlink_target;
+ guint32 attribute;
+ GFileAttributeType type;
+ union {
+ gint32 int32;
+ guint32 uint32;
+ gint64 int64;
+ guint64 uint64;
+ char *string;
+ GQuark quark;
+ } value;
+} GFileAttributeValue;
+
+struct _GFileInfo
+{
+ GObject parent_instance;
+
GArray *attributes;
- guint is_hidden : 1;
};
-static void
-g_file_info_finalize (GObject *object)
+G_DEFINE_TYPE (GFileInfo, g_file_info, G_TYPE_OBJECT);
+
+typedef struct {
+ guint32 id;
+ guint32 attribute_id_counter;
+} NSInfo;
+
+G_LOCK_DEFINE_STATIC (attribute_hash);
+static int namespace_id_counter = 0;
+static GHashTable *ns_hash = NULL;
+static GHashTable *attribute_hash = NULL;
+static char ***attributes = NULL;
+
+/* Attribute ids are 32bit, we split it up like this:
+ * |------------|--------------------|
+ * 12 bit 20 bit
+ * namespace attribute id
+ *
+ * This way the attributes gets sorted in namespace order
+ */
+
+#define NS_POS 20
+#define NS_MASK ((guint32)((1<<12) - 1))
+#define ID_POS 0
+#define ID_MASK ((guint32)((1<<20) - 1))
+
+#define GET_NS(_attr_id) \
+ (((guint32) (_attr_id) >> NS_POS) & NS_MASK)
+#define GET_ID(_attr_id) \
+ (((guint32)(_attr_id) >> ID_POS) & ID_MASK)
+
+#define MAKE_ATTR_ID(_ns, _id) \
+ ( ((((guint32) _ns) & NS_MASK) << NS_POS) | \
+ ((((guint32) _id) & ID_MASK) << ID_POS) )
+
+static NSInfo *
+_lookup_namespace (const char *namespace)
{
- GFileInfo *info;
- GFileInfoPrivate *priv;
- GFileAttributeInternal *internal;
- GArray *attrs;
- int i;
+ NSInfo *ns_info;
+
+ ns_info = g_hash_table_lookup (ns_hash, namespace);
+ if (ns_info == NULL)
+ {
+ ns_info = g_new0 (NSInfo, 1);
+ ns_info->id = ++namespace_id_counter;
+ g_hash_table_insert (ns_hash, g_strdup (namespace), ns_info);
+ attributes = g_realloc (attributes, (ns_info->id + 1) * sizeof (char **));
+ attributes[ns_info->id] = NULL;
+ }
+ return ns_info;
+}
- info = G_FILE_INFO (object);
+static guint32
+lookup_namespace (const char *namespace)
+{
+ NSInfo *ns_info;
+ guint32 id;
+
+ G_LOCK (attribute_hash);
+
+ if (attribute_hash == NULL)
+ {
+ ns_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ attribute_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ }
+
+ ns_info = _lookup_namespace (namespace);
+ id = 0;
+ if (ns_info)
+ id = ns_info->id;
+
+ G_UNLOCK (attribute_hash);
- priv = info->priv;
+ return id;
+}
+
+
+static char *
+get_attribute_for_id (int attribute)
+{
+ char *s;
+ G_LOCK (attribute_hash);
+ s = attributes[GET_NS(attribute)][GET_ID(attribute)];
+ G_UNLOCK (attribute_hash);
+ return s;
+}
+
+static guint32
+lookup_attribute (const char *attribute)
+{
+ guint32 attr_id, id;
+ char *ns;
+ const char *colon;
+ NSInfo *ns_info;
- g_free (priv->name);
- g_free (priv->display_name);
- g_free (priv->icon);
- g_free (priv->stat_info);
- g_free (priv->symlink_target);
+ G_LOCK (attribute_hash);
+ if (attribute_hash == NULL)
+ {
+ ns_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ attribute_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ }
- attrs = info->priv->attributes;
- for (i = 0; i < attrs->len; i++)
+ attr_id = GPOINTER_TO_UINT (g_hash_table_lookup (attribute_hash, attribute));
+
+ if (attr_id != 0)
{
- internal = &g_array_index (attrs, GFileAttributeInternal, i);
- g_free (internal->value);
+ G_UNLOCK (attribute_hash);
+ return attr_id;
}
+
+ colon = strchr (attribute, ':');
+ if (colon)
+ ns = g_strndup (attribute, colon - attribute);
+ else
+ ns = g_strdup ("");
+
+ ns_info = _lookup_namespace (ns);
+ g_free (ns);
+
+ id = ++ns_info->attribute_id_counter;
+ attributes[ns_info->id] = g_realloc (attributes[ns_info->id], (id + 1) * sizeof (char *));
+ attributes[ns_info->id][id] = g_strdup (attribute);
- g_array_free (priv->attributes, TRUE);
+ attr_id = MAKE_ATTR_ID (ns_info->id, id);
+
+ g_hash_table_insert (attribute_hash, attributes[ns_info->id][id], GUINT_TO_POINTER (attr_id));
+
+ G_UNLOCK (attribute_hash);
+
+ return attr_id;
+}
+
+static void
+free_attribute_value (GFileAttributeValue *value)
+{
+ if (value->type == G_FILE_ATTRIBUTE_TYPE_STRING)
+ g_free (value->value.string);
+}
+
+static void
+g_file_info_finalize (GObject *object)
+{
+ GFileInfo *info;
+ int i;
+ GFileAttributeValue *values;
+
+ info = G_FILE_INFO (object);
+
+ values = (GFileAttributeValue *)info->attributes->data;
+ for (i = 0; i < info->attributes->len; i++)
+ free_attribute_value (&values[i]);
+ g_array_free (info->attributes, TRUE);
if (G_OBJECT_CLASS (g_file_info_parent_class)->finalize)
(*G_OBJECT_CLASS (g_file_info_parent_class)->finalize) (object);
@@ -68,21 +188,14 @@ g_file_info_class_init (GFileInfoClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- g_type_class_add_private (klass, sizeof (GFileInfoPrivate));
-
gobject_class->finalize = g_file_info_finalize;
}
static void
g_file_info_init (GFileInfo *info)
{
- info->priv = G_TYPE_INSTANCE_GET_PRIVATE (info,
- G_TYPE_FILE_INFO,
- GFileInfoPrivate);
-
- info->priv->attributes = g_array_new (FALSE,
- FALSE,
- sizeof (GFileAttributeInternal));
+ info->attributes = g_array_new (FALSE, FALSE,
+ sizeof (GFileAttributeValue));
}
GFileInfo *
@@ -91,523 +204,917 @@ g_file_info_new (void)
return g_object_new (G_TYPE_FILE_INFO, NULL);
}
-GFileType
-g_file_info_get_file_type (GFileInfo *info)
+GFileInfo *
+g_file_info_copy (GFileInfo *other)
{
- return info->priv->file_type;
+ GFileInfo *new;
+
+ new = g_file_info_new ();
+ g_array_append_vals (new->attributes,
+ other->attributes->data,
+ other->attributes->len);
+
+ return new;
}
-const char *
-g_file_info_get_name (GFileInfo *info)
+static int
+g_file_info_find_place (GFileInfo *info,
+ guint32 attribute)
{
- return info->priv->name;
+ int min, max, med;
+ GFileAttributeValue *values;
+ /* Binary search for the place where attribute would be, if its
+ in the array */
+
+ min = 0;
+ max = info->attributes->len;
+
+ values = (GFileAttributeValue *)info->attributes->data;
+
+ while (min < max)
+ {
+ med = min + (max - min) / 2;
+ if (values[med].attribute == attribute)
+ {
+ min = med;
+ break;
+ }
+ else if (values[med].attribute < attribute)
+ min = med + 1;
+ else /* values[med].attribute > attribute */
+ max = med;
+ }
+
+ return min;
}
-const char *
-g_file_info_get_display_name (GFileInfo *info)
+
+static GFileAttributeValue *
+g_file_info_find_value (GFileInfo *info,
+ guint32 attr_id)
{
- return info->priv->display_name;
+ GFileAttributeValue *values;
+ int i;
+
+ i = g_file_info_find_place (info, attr_id);
+ values = (GFileAttributeValue *)info->attributes->data;
+ if (i < info->attributes->len &&
+ values[i].attribute == attr_id)
+ return &values[i];
+
+ return NULL;
}
-const char *
-g_file_info_get_edit_name (GFileInfo *info)
+static GFileAttributeValue *
+g_file_info_find_value_by_name (GFileInfo *info,
+ const char *attribute)
{
- return info->priv->edit_name;
+ guint32 attr_id;
+
+ attr_id = lookup_attribute (attribute);
+ return g_file_info_find_value (info, attr_id);
}
-const char *
-g_file_info_get_icon (GFileInfo *info)
+
+gboolean
+g_file_info_has_attribute (GFileInfo *info,
+ const char *attribute)
{
- return info->priv->icon;
+ GFileAttributeValue *value;
+
+ value = g_file_info_find_value_by_name (info, attribute);
+ return value != NULL;
}
-const char *
-g_file_info_get_mime_type (GFileInfo *info)
+char **
+g_file_info_list_attributes (GFileInfo *info,
+ const char *name_space)
{
- return g_quark_to_string (info->priv->mime_type_q);
+ GPtrArray *names;
+ GFileAttributeValue *values;
+ guint32 attribute;
+ int i;
+
+ names = g_ptr_array_new ();
+ values = (GFileAttributeValue *)info->attributes->data;
+ for (i = 0; i < info->attributes->len; i++)
+ {
+ attribute = values[i].attribute;
+ g_ptr_array_add (names, g_strdup (get_attribute_for_id (attribute)));
+ }
+
+ /* NULL terminate */
+ g_ptr_array_add (names, NULL);
+
+ return (char **)g_ptr_array_free (names, FALSE);
}
-GQuark
-g_file_info_get_mime_type_quark (GFileInfo *info)
+
+GFileAttributeType
+g_file_info_get_attribute_type (GFileInfo *info,
+ const char *attribute)
{
- return info->priv->mime_type_q;
+ GFileAttributeValue *value;
+
+ value = g_file_info_find_value_by_name (info, attribute);
+ if (value)
+ return value->type;
+ else
+ return G_FILE_ATTRIBUTE_TYPE_INVALID;
}
-goffset
-g_file_info_get_size (GFileInfo *info)
+void
+g_file_info_remove_attribute (GFileInfo *info,
+ const char *attribute)
{
- return info->priv->size;
-}
+
+ guint32 attr_id;
+ GFileAttributeValue *values;
+ int i;
+
+ attr_id = lookup_attribute (attribute);
-time_t
-g_file_info_get_modification_time (GFileInfo *info)
+ i = g_file_info_find_place (info, attr_id);
+ values = (GFileAttributeValue *)info->attributes->data;
+ if (i < info->attributes->len &&
+ values[i].attribute == attr_id)
+ {
+ free_attribute_value (&values[i]);
+ g_array_remove_index (info->attributes, i);
+ }
+}
+
+static gboolean
+valid_char (char c)
{
- return info->priv->mtime;
+ return c >= 32 && c <= 126 && c != '\\';
}
-const char *
-g_file_info_get_symlink_target (GFileInfo *info)
+static char *
+escape_byte_string (const char *str)
{
- return info->priv->symlink_target;
+ size_t len;
+ int num_invalid, i;
+ char *escaped_val, *p;
+ unsigned char c;
+ char *hex_digits = "0123456789abcdef";
+
+ len = strlen (str);
+
+ num_invalid = 0;
+ for (i = 0; i < len; i++)
+ {
+ if (!valid_char (str[i]))
+ num_invalid++;
+ }
+
+ if (num_invalid == 0)
+ return g_strdup (str);
+ else
+ {
+ escaped_val = g_malloc (len + num_invalid*3 + 1);
+
+ p = escaped_val;
+ for (i = 0; i < len; i++)
+ {
+ c = str[i];
+ if (valid_char (c))
+ *p++ = c;
+ else
+ {
+ *p++ = '\\';
+ *p++ = 'x';
+ *p++ = hex_digits[(c >> 8) & 0xf];
+ *p++ = hex_digits[c & 0xf];
+ }
+ }
+ *p++ = 0;
+ return escaped_val;
+ }
}
-GFileAccessRights
-g_file_info_get_access_rights (GFileInfo *info)
+
+char *
+g_file_info_get_attribute_as_string (GFileInfo *info,
+ const char *attribute)
{
- return info->priv->access_rights;
+ GFileAttributeValue *value;
+ char *str;
+
+ value = g_file_info_find_value_by_name (info, attribute);
+
+ if (value == NULL)
+ return NULL;
+
+ switch (value->type)
+ {
+ case G_FILE_ATTRIBUTE_TYPE_STRING:
+ str = g_strdup (value->value.string);
+ break;
+ case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
+ str = escape_byte_string (value->value.string);
+ break;
+ case G_FILE_ATTRIBUTE_TYPE_UINT32:
+ str = g_strdup_printf ("%u", (unsigned int)value->value.uint32);
+ break;
+ case G_FILE_ATTRIBUTE_TYPE_INT32:
+ str = g_strdup_printf ("%i", (int)value->value.int32);
+ break;
+ case G_FILE_ATTRIBUTE_TYPE_UINT64:
+ str = g_strdup_printf ("%"G_GUINT64_FORMAT, value->value.uint64);
+ break;
+ case G_FILE_ATTRIBUTE_TYPE_INT64:
+ str = g_strdup_printf ("%"G_GINT64_FORMAT, value->value.int64);
+ break;
+ default:
+ g_warning ("Invalid type in GFileInfo attribute");
+ str = g_strdup ("");
+ break;
+ }
+
+ return str;
}
-gboolean
-g_file_info_can_read (GFileInfo *info)
+static char *
+get_string (GFileAttributeValue *value)
{
- return info->priv->access_rights & G_FILE_ACCESS_CAN_READ;
+ if (value == NULL || value->type != G_FILE_ATTRIBUTE_TYPE_STRING)
+ {
+ if (value != NULL)
+ g_warning ("Invalid type in GFileInfo attribute");
+ return NULL;
+ }
+ return value->value.string;
}
-gboolean
-g_file_info_can_write (GFileInfo *info)
+static char *
+get_byte_string (GFileAttributeValue *value)
{
- return info->priv->access_rights & G_FILE_ACCESS_CAN_WRITE;
+ if (value == NULL || value->type != G_FILE_ATTRIBUTE_TYPE_BYTE_STRING)
+ {
+ if (value != NULL)
+ g_warning ("Invalid type in GFileInfo attribute");
+ return NULL;
+ }
+ return value->value.string;
}
-gboolean
-g_file_info_can_delete (GFileInfo *info)
+static guint32
+get_uint32 (GFileAttributeValue *value)
{
- return info->priv->access_rights & G_FILE_ACCESS_CAN_DELETE;
+ if (value == NULL || value->type != G_FILE_ATTRIBUTE_TYPE_UINT32)
+ {
+ if (value != NULL)
+ g_warning ("Invalid type in GFileInfo attribute");
+ return 0;
+ }
+ return value->value.uint32;
}
-gboolean
-g_file_info_can_rename (GFileInfo *info)
+static gint32
+get_int32 (GFileAttributeValue *value)
{
- return info->priv->access_rights & G_FILE_ACCESS_CAN_RENAME;
+ if (value == NULL || value->type != G_FILE_ATTRIBUTE_TYPE_INT32)
+ {
+ if (value != NULL)
+ g_warning ("Invalid type in GFileInfo attribute");
+ return 0;
+ }
+ return value->value.int32;
}
-gboolean
-g_file_info_get_is_hidden (GFileInfo *info)
+static guint64
+get_uint64 (GFileAttributeValue *value)
{
- return info->priv->is_hidden;
+ if (value == NULL || value->type != G_FILE_ATTRIBUTE_TYPE_UINT64)
+ {
+ if (value != NULL)
+ g_warning ("Invalid type in GFileInfo attribute");
+ return 0;
+ }
+ return value->value.uint64;
}
-const struct stat *
-g_file_info_get_stat_info (GFileInfo *info)
+static gint64
+get_int64 (GFileAttributeValue *value)
{
- return info->priv->stat_info;
+ if (value == NULL || value->type != G_FILE_ATTRIBUTE_TYPE_INT64)
+ {
+ if (value != NULL)
+ g_warning ("Invalid type in GFileInfo attribute");
+ return 0;
+ }
+ return value->value.int64;
}
const char *
-g_file_info_get_attribute (GFileInfo *info,
- const char *attribute)
+g_file_info_get_attribute_string (GFileInfo *info,
+ const char *attribute)
{
- GFileAttributeInternal *internal;
- GQuark attr_q;
- GArray *attrs;
- int i;
-
- attr_q = g_quark_try_string (attribute);
- if (attr_q == 0)
- return NULL;
+ GFileAttributeValue *value;
- attrs = info->priv->attributes;
- for (i = 0; i < attrs->len; i++)
- {
- internal = &g_array_index (attrs, GFileAttributeInternal, i);
- if (internal->attribute_q == attr_q)
- return internal->value;
- }
-
- return NULL;
+ value = g_file_info_find_value_by_name (info, attribute);
+ return get_string (value);
}
-
-GFileAttribute *
-g_file_info_get_attributes (GFileInfo *info,
- const char *namespace,
- int *n_attributes)
+
+const char *
+g_file_info_get_attribute_byte_string (GFileInfo *info,
+ const char *attribute)
{
- GFileAttributeInternal *internal;
- GQuark namespace_q;
- GArray *attrs;
- GArray *result;
- int i;
+ GFileAttributeValue *value;
- *n_attributes = 0;
-
- namespace_q = g_quark_try_string (namespace);
- if (namespace_q == 0)
- return NULL;
+ value = g_file_info_find_value_by_name (info, attribute);
+ return get_byte_string (value);
+}
- result = g_array_new (FALSE, FALSE, sizeof (GFileAttribute));
-
- attrs = info->priv->attributes;
- for (i = 0; i < attrs->len; i++)
- {
- internal = &g_array_index (attrs, GFileAttributeInternal, i);
-
- if (internal->namespace_q == namespace_q)
- {
- GFileAttribute attr;
- attr.attribute = g_quark_to_string (internal->attribute_q);
- attr.value = internal->value;
- g_array_append_val (result, attr);
- }
- }
+guint32
+g_file_info_get_attribute_uint32 (GFileInfo *info,
+ const char *attribute)
+{
+ GFileAttributeValue *value;
+ value = g_file_info_find_value_by_name (info, attribute);
+ return get_uint32 (value);
+}
- *n_attributes = result->len;
+gint32
+g_file_info_get_attribute_int32 (GFileInfo *info,
+ const char *attribute)
+{
+ GFileAttributeValue *value;
- if (result->len == 0)
- {
- g_array_free (result, TRUE);
- return NULL;
- }
+ value = g_file_info_find_value_by_name (info, attribute);
+ return get_int32 (value);
+}
+
+guint64
+g_file_info_get_attribute_uint64 (GFileInfo *info,
+ const char *attribute)
+{
+ GFileAttributeValue *value;
- return (GFileAttribute *)g_array_free (result, FALSE);
+ value = g_file_info_find_value_by_name (info, attribute);
+ return get_uint64 (value);
}
-
-GFileAttribute *
-g_file_info_get_all_attributes (GFileInfo *info,
- int *n_attributes)
+
+gint64
+g_file_info_get_attribute_int64 (GFileInfo *info,
+ const char *attribute)
{
- GFileAttributeInternal *internal;
- GArray *attrs;
- GArray *result;
+ GFileAttributeValue *value;
+
+ value = g_file_info_find_value_by_name (info, attribute);
+ return get_int64 (value);
+}
+
+static GFileAttributeValue *
+g_file_info_create_value (GFileInfo *info,
+ guint32 attr_id)
+{
+ GFileAttributeValue *values;
+ GFileAttributeValue value;
int i;
- *n_attributes = 0;
-
- result = g_array_new (FALSE, FALSE, sizeof (GFileAttribute));
+ i = g_file_info_find_place (info, attr_id);
- attrs = info->priv->attributes;
- for (i = 0; i < attrs->len; i++)
+ values = (GFileAttributeValue *)info->attributes->data;
+ if (i < info->attributes->len &&
+ values[i].attribute == attr_id)
+ return &values[i];
+ else
{
- GFileAttribute attr;
- internal = &g_array_index (attrs, GFileAttributeInternal, i);
-
- attr.attribute = g_quark_to_string (internal->attribute_q);
- attr.value = internal->value;
- g_array_append_val (result, attr);
+ value.attribute = attr_id;
+ value.type = G_FILE_ATTRIBUTE_TYPE_INVALID;
+ g_array_insert_val (info->attributes, i , value);
+
+ values = (GFileAttributeValue *)info->attributes->data;
+ return &values[i];
}
+}
- *n_attributes = result->len;
+static GFileAttributeValue *
+g_file_info_create_value_by_name (GFileInfo *info,
+ const char *attribute)
+{
+ guint32 attr_id;
- if (result->len == 0)
- {
- g_array_free (result, TRUE);
- return NULL;
- }
+ attr_id = lookup_attribute (attribute);
- return (GFileAttribute *)g_array_free (result, FALSE);
-}
+ return g_file_info_create_value (info, attr_id);
+}
-void
-g_file_info_set_file_type (GFileInfo *info,
- GFileType file_type)
+static void
+set_string (GFileAttributeValue *value, const char *string)
{
- info->priv->file_type = file_type;
+ free_attribute_value (value);
+ value->type = G_FILE_ATTRIBUTE_TYPE_STRING;
+ value->value.string = g_strdup (string);
}
-
-void
-g_file_info_set_name (GFileInfo *info,
- const char *name)
+
+static void
+set_byte_string (GFileAttributeValue *value, const char *string)
{
- g_free (info->priv->name);
- info->priv->name = g_strdup (name);
+ free_attribute_value (value);
+ value->type = G_FILE_ATTRIBUTE_TYPE_BYTE_STRING;
+ value->value.string = g_strdup (string);
}
-void
-g_file_info_set_display_name (GFileInfo *info,
- const char *display_name)
+static void
+set_uint32 (GFileAttributeValue *value, guint32 val)
{
- g_free (info->priv->display_name);
- info->priv->display_name = g_strdup (display_name);
+ free_attribute_value (value);
+ value->type = G_FILE_ATTRIBUTE_TYPE_UINT32;
+ value->value.uint32 = val;
+}
+
+static void
+set_int32 (GFileAttributeValue *value, gint32 val)
+{
+ free_attribute_value (value);
+ value->type = G_FILE_ATTRIBUTE_TYPE_INT32;
+ value->value.int32 = val;
+}
+
+static void
+set_uint64 (GFileAttributeValue *value, guint64 val)
+{
+ free_attribute_value (value);
+ value->type = G_FILE_ATTRIBUTE_TYPE_UINT64;
+ value->value.uint64 = val;
+}
+
+static void
+set_int64 (GFileAttributeValue *value, gint64 val)
+{
+ free_attribute_value (value);
+ value->type = G_FILE_ATTRIBUTE_TYPE_INT64;
+ value->value.int64 = val;
}
void
-g_file_info_set_edit_name (GFileInfo *info,
- const char *edit_name)
+g_file_info_set_attribute_string (GFileInfo *info,
+ const char *attribute,
+ const char *attr_value)
{
- g_free (info->priv->edit_name);
- info->priv->edit_name = g_strdup (edit_name);
+ GFileAttributeValue *value;
+
+ value = g_file_info_create_value_by_name (info, attribute);
+ set_string (value, attr_value);
}
void
-g_file_info_set_icon (GFileInfo *info,
- const char *icon)
+g_file_info_set_attribute_byte_string (GFileInfo *info,
+ const char *attribute,
+ const char *attr_value)
{
- g_free (info->priv->icon);
- info->priv->icon = g_strdup (icon);
+ GFileAttributeValue *value;
+
+ value = g_file_info_create_value_by_name (info, attribute);
+ set_byte_string (value, attr_value);
}
void
-g_file_info_set_mime_type (GFileInfo *info,
- const char *mime_type)
+g_file_info_set_attribute_uint32 (GFileInfo *info,
+ const char *attribute,
+ guint32 attr_value)
{
- info->priv->mime_type_q = g_quark_from_string (mime_type);
+ GFileAttributeValue *value;
+
+ value = g_file_info_create_value_by_name (info, attribute);
+ set_uint32 (value, attr_value);
}
void
-g_file_info_set_size (GFileInfo *info,
- goffset size)
+g_file_info_set_attribute_int32 (GFileInfo *info,
+ const char *attribute,
+ gint32 attr_value)
{
- info->priv->size = size;
+ GFileAttributeValue *value;
+
+ value = g_file_info_create_value_by_name (info, attribute);
+ set_int32 (value, attr_value);
}
void
-g_file_info_set_modification_time (GFileInfo *info,
- time_t mtime)
+g_file_info_set_attribute_uint64 (GFileInfo *info,
+ const char *attribute,
+ guint64 attr_value)
{
- info->priv->mtime = mtime;
+ GFileAttributeValue *value;
+
+ value = g_file_info_create_value_by_name (info, attribute);
+ set_uint64 (value, attr_value);
}
void
-g_file_info_set_symlink_target (GFileInfo *info,
- const char *link_target)
+g_file_info_set_attribute_int64 (GFileInfo *info,
+ const char *attribute,
+ gint64 attr_value)
{
- g_free (info->priv->symlink_target);
- info->priv->symlink_target = g_strdup (link_target);
+ GFileAttributeValue *value;
+
+ value = g_file_info_create_value_by_name (info, attribute);
+ set_int64 (value, attr_value);
}
+
+/* Helper getters */
+GFileType
+g_file_info_get_file_type (GFileInfo *info)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
-void
-g_file_info_set_access_rights (GFileInfo *info,
- GFileAccessRights access_rights)
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_TYPE);
+
+ value = g_file_info_find_value (info, attr);
+ return (GFileType)get_uint32 (value);
+}
+
+GFileFlags
+g_file_info_get_flags (GFileInfo *info)
{
- info->priv->access_rights = access_rights;
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_FLAGS);
+
+ value = g_file_info_find_value (info, attr);
+ return (GFileType)get_uint32 (value);
}
-void
-g_file_info_set_is_hidden (GFileInfo *info,
- gboolean is_hidden)
+const char *
+g_file_info_get_name (GFileInfo *info)
{
- info->priv->is_hidden = is_hidden;
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_NAME);
+
+ value = g_file_info_find_value (info, attr);
+ return get_byte_string (value);
}
-void
-g_file_info_set_stat_info (GFileInfo *info,
- const struct stat *statbuf)
+const char *
+g_file_info_get_display_name (GFileInfo *info)
{
- if (statbuf == NULL)
- {
- g_free (info->priv->stat_info);
- info->priv->stat_info = NULL;
- }
- else
- {
- if (info->priv->stat_info == NULL)
- info->priv->stat_info = g_new (struct stat, 1);
- *info->priv->stat_info = *statbuf;
- }
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_DISPLAY_NAME);
+
+ value = g_file_info_find_value (info, attr);
+ return get_string (value);
}
-void
-g_file_info_set_from_stat (GFileInfo *info,
- GFileInfoRequestFlags requested,
- const struct stat *statbuf)
+const char *
+g_file_info_get_edit_name (GFileInfo *info)
{
- if (requested & G_FILE_INFO_FILE_TYPE)
- {
- if (S_ISREG (statbuf->st_mode))
- info->priv->file_type = G_FILE_TYPE_REGULAR;
- else if (S_ISDIR (statbuf->st_mode))
- info->priv->file_type = G_FILE_TYPE_DIRECTORY;
- else if (S_ISCHR (statbuf->st_mode) ||
- S_ISBLK (statbuf->st_mode) ||
- S_ISFIFO (statbuf->st_mode)
-#ifdef S_ISSOCK
- || S_ISSOCK (statbuf->st_mode)
-#endif
- )
- info->priv->file_type = G_FILE_TYPE_SPECIAL;
- else if (S_ISLNK (statbuf->st_mode))
- info->priv->file_type = G_FILE_TYPE_SYMBOLIC_LINK;
- else
- info->priv->file_type = G_FILE_TYPE_UNKNOWN;
- }
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_EDIT_NAME);
- if (requested & G_FILE_INFO_SIZE)
- g_file_info_set_size (info, statbuf->st_size);
+ value = g_file_info_find_value (info, attr);
+ return get_string (value);
+}
- if (requested & G_FILE_INFO_MODIFICATION_TIME)
- g_file_info_set_modification_time (info, statbuf->st_mtime);
+const char *
+g_file_info_get_icon (GFileInfo *info)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
- if (requested & G_FILE_INFO_STAT_INFO)
- g_file_info_set_stat_info (info, statbuf);
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_ICON);
+
+ value = g_file_info_find_value (info, attr);
+ return get_string (value);
}
+const char *
+g_file_info_get_mime_type (GFileInfo *info)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_MIME_TYPE);
+
+ value = g_file_info_find_value (info, attr);
+ return get_string (value);
+}
-void
-g_file_info_set_attribute (GFileInfo *info,
- const char *attribute,
- const char *value)
-{
- GFileAttributeInternal new_internal;
- GArray *attrs;
- GQuark attr_q;
- char *colon, *namespace;
- int i;
+goffset
+g_file_info_get_size (GFileInfo *info)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
- attr_q = g_quark_from_string (attribute);
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_SIZE);
+
+ value = g_file_info_find_value (info, attr);
+ return (goffset) get_uint64 (value);
+}
+
+void
+g_file_info_get_modification_time (GFileInfo *info,
+ GTimeVal *result)
+{
+ static guint32 attr_mtime = 0, attr_mtime_usec;
+ GFileAttributeValue *value;
- attrs = info->priv->attributes;
- for (i = 0; i < attrs->len; i++)
+ if (attr_mtime == 0)
{
- GFileAttributeInternal *internal = &g_array_index (attrs, GFileAttributeInternal, i);
-
- if (internal->attribute_q == attr_q)
- {
- g_free (internal->value);
- internal->value = g_strdup (value);
- return;
- }
+ attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_STD_MTIME);
+ attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_STD_MTIME_USEC);
}
+
+ value = g_file_info_find_value (info, attr_mtime);
+ result->tv_sec = get_uint64 (value);
+ value = g_file_info_find_value (info, attr_mtime_usec);
+ result->tv_usec = get_uint32 (value);
+}
- new_internal.value = g_strdup (value);
- new_internal.attribute_q = g_quark_from_string (attribute);
+const char *
+g_file_info_get_symlink_target (GFileInfo *info)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_SYMLINK_TARGET);
+
+ value = g_file_info_find_value (info, attr);
+ return get_byte_string (value);
+}
- colon = strchr (attribute, ':');
- if (colon && colon != attribute) {
- namespace = g_strndup (attribute, colon - attribute);
- new_internal.namespace_q = g_quark_from_string (namespace);
- g_free (namespace);
- } else {
- new_internal.namespace_q = 0;
- }
+GFileAccessRights
+g_file_info_get_access_rights (GFileInfo *info)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_ACCESS_RIGHTS);
+
+ value = g_file_info_find_value (info, attr);
+ return (goffset) get_uint32 (value);
+}
- g_array_append_val(attrs,new_internal);
+GFileAccessRights
+g_file_info_get_access_rights_mask (GFileInfo *info)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_ACCESS_RIGHTS_MASK);
+
+ value = g_file_info_find_value (info, attr);
+ return (goffset) get_uint32 (value);
}
+/* Helper setters: */
+
void
-g_file_info_set_attributes (GFileInfo *info,
- GFileAttribute *attributes,
- int n_attributes)
+g_file_info_set_file_type (GFileInfo *info,
+ GFileType type)
{
- int i;
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
- for (i = 0; i < n_attributes; i++) {
- g_file_info_set_attribute (info,
- attributes[i].attribute,
- attributes[i].value);
- }
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_TYPE);
+
+ value = g_file_info_create_value (info, attr);
+ set_uint32 (value, type);
}
-#define ON_STACK_NAMESPACES 3
-#define ON_STACK_ATTRIBUTES 3
+void
+g_file_info_set_flags (GFileInfo *info,
+ GFileFlags flags)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_FLAGS);
+
+ value = g_file_info_create_value (info, attr);
+ set_uint32 (value, flags);
+}
-typedef struct {
- GQuark namespace;
- gboolean all;
- GQuark full_names[ON_STACK_ATTRIBUTES];
- GArray *more_full_names;
-} NamespaceMatcher;
+void
+g_file_info_set_name (GFileInfo *info,
+ const char *name)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_NAME);
+
+ value = g_file_info_create_value (info, attr);
+ set_byte_string (value, name);
+}
-struct _GFileAttributeMatcher {
- gboolean all;
- NamespaceMatcher namespaces[ON_STACK_NAMESPACES];
- GArray *more_namespaces;
+void
+g_file_info_set_display_name (GFileInfo *info,
+ const char *display_name)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_DISPLAY_NAME);
+
+ value = g_file_info_create_value (info, attr);
+ set_string (value, display_name);
+}
- /* Interator */
- NamespaceMatcher *matched_namespace;
- int attribute_pos;
-};
+void
+g_file_info_set_edit_name (GFileInfo *info,
+ const char *edit_name)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_EDIT_NAME);
+
+ value = g_file_info_create_value (info, attr);
+ set_string (value, edit_name);
+}
-static NamespaceMatcher *
-matcher_find_namespace (GFileAttributeMatcher *matcher,
- GQuark namespace_q,
- gboolean create)
+void
+g_file_info_set_icon (GFileInfo *info,
+ const char *icon)
{
- NamespaceMatcher *ns_matcher;
- int i;
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
- for (i = 0; i < ON_STACK_NAMESPACES; i++)
- {
- ns_matcher = &matcher->namespaces[i];
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_ICON);
+
+ value = g_file_info_create_value (info, attr);
+ set_string (value, icon);
+}
- /* First empty spot, not found, use this */
- if (ns_matcher->namespace == 0)
- {
- if (create)
- {
- ns_matcher->namespace = namespace_q;
- return ns_matcher;
- }
- else
- return NULL;
- }
+void
+g_file_info_set_mime_type (GFileInfo *info,
+ const char *mime_type)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_MIME_TYPE);
+
+ value = g_file_info_create_value (info, attr);
+ set_string (value, mime_type);
+}
- /* Found, use this */
- if (ns_matcher->namespace == namespace_q)
- return ns_matcher;
- }
+void
+g_file_info_set_size (GFileInfo *info,
+ goffset size)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_SIZE);
+
+ value = g_file_info_create_value (info, attr);
+ set_uint64 (value, size);
+}
- if (matcher->more_namespaces == NULL)
+void
+g_file_info_set_modification_time (GFileInfo *info,
+ GTimeVal *mtime)
+{
+ static guint32 attr_mtime = 0, attr_mtime_usec;
+ GFileAttributeValue *value;
+
+ if (attr_mtime == 0)
{
- if (create)
- matcher->more_namespaces = g_array_new (FALSE, FALSE, sizeof (NamespaceMatcher));
- else
- return NULL;
+ attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_STD_MTIME);
+ attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_STD_MTIME_USEC);
}
+
+ value = g_file_info_create_value (info, attr_mtime);
+ set_uint64 (value, mtime->tv_sec);
+ value = g_file_info_create_value (info, attr_mtime_usec);
+ set_uint32 (value, mtime->tv_usec);
+}
- for (i = 0; i < matcher->more_namespaces->len; i++)
- {
- ns_matcher = &g_array_index (matcher->more_namespaces, NamespaceMatcher, i);
- if (ns_matcher->namespace == namespace_q)
- return ns_matcher;
- }
+void
+g_file_info_set_symlink_target (GFileInfo *info,
+ const char *symlink_target)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
- if (create)
- {
- NamespaceMatcher new_space = {namespace_q};
- g_array_append_val (matcher->more_namespaces, new_space);
- ns_matcher = &g_array_index (matcher->more_namespaces, NamespaceMatcher, i);
- return ns_matcher;
- }
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_SYMLINK_TARGET);
- return NULL;
+ value = g_file_info_create_value (info, attr);
+ set_byte_string (value, symlink_target);
+}
+
+void
+g_file_info_set_access_rights (GFileInfo *info,
+ GFileAccessRights rights)
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_ACCESS_RIGHTS);
+
+ value = g_file_info_create_value (info, attr);
+ set_uint32 (value, rights);
+}
+
+void
+g_file_info_set_access_rights_mask (GFileInfo *info,
+ GFileAccessRights mask)
+
+{
+ static guint32 attr = 0;
+ GFileAttributeValue *value;
+
+ if (attr == 0)
+ attr = lookup_attribute (G_FILE_ATTRIBUTE_STD_ACCESS_RIGHTS_MASK);
+
+ value = g_file_info_create_value (info, attr);
+ set_uint32 (value, mask);
}
+#define ON_STACK_MATCHERS 5
+
+typedef struct {
+ guint32 id;
+ guint32 mask;
+} SubMatcher;
+
+struct _GFileAttributeMatcher {
+ gboolean all;
+ SubMatcher sub_matchers[ON_STACK_MATCHERS];
+ GArray *more_sub_matchers;
+
+ /* Interator */
+ guint32 iterator_ns;
+ int iterator_pos;
+};
+
static void
-matcher_add_namespace (GFileAttributeMatcher *matcher,
- GQuark namespace_q,
- GQuark full_name_q)
+matcher_add (GFileAttributeMatcher *matcher,
+ guint id, guint mask)
{
+ SubMatcher *sub_matchers;
int i;
- NamespaceMatcher *ns_matcher;
-
- ns_matcher = matcher_find_namespace (matcher, namespace_q, TRUE);
+ SubMatcher s;
- if (full_name_q == 0)
- ns_matcher->all = TRUE;
- else
+ for (i = 0; i < ON_STACK_MATCHERS; i++)
{
- for (i = 0; i < ON_STACK_ATTRIBUTES; i++)
+ /* First empty spot, not found, use this */
+ if (matcher->sub_matchers[i].id == 0)
{
-
- /* First empty spot, not found, use this */
- if (ns_matcher->full_names[i] == 0)
- {
- ns_matcher->full_names[i] = full_name_q;
- break;
- }
-
- /* Already added */
- if (ns_matcher->full_names[i] == namespace_q)
- break;
+ matcher->sub_matchers[i].id = id;
+ matcher->sub_matchers[i].mask = mask;
+ return;
}
- if (i == ON_STACK_ATTRIBUTES)
- {
- if (ns_matcher->more_full_names == NULL)
- ns_matcher->more_full_names = g_array_new (FALSE, FALSE, sizeof (GQuark));
+ /* Already added */
+ if (matcher->sub_matchers[i].id == id &&
+ matcher->sub_matchers[i].mask == mask)
+ return;
+ }
- for (i = 0; i < ns_matcher->more_full_names->len; i++)
- {
- GQuark existing_name = g_array_index (ns_matcher->more_full_names, GQuark, i);
- if (existing_name == full_name_q)
- break;
- }
-
- g_array_append_val (ns_matcher->more_full_names, full_name_q);
- }
+ if (matcher->more_sub_matchers == NULL)
+ matcher->more_sub_matchers = g_array_new (FALSE, FALSE, sizeof (SubMatcher));
+
+ sub_matchers = (SubMatcher *)matcher->more_sub_matchers->data;
+ for (i = 0; i < matcher->more_sub_matchers->len; i++)
+ {
+ /* Already added */
+ if (sub_matchers[i].id == id &&
+ sub_matchers[i].mask == mask)
+ return;
}
+
+ s.id = id;
+ s.mask = mask;
+
+ g_array_append_val (matcher->more_sub_matchers, s);
}
@@ -617,9 +1124,6 @@ g_file_attribute_matcher_new (const char *attributes)
char **split;
char *colon;
int i;
- int num_ns, num_fn;
- GQuark full_name_q, namespace_q;
- GArray *full_name_array, *namespace_array;
GFileAttributeMatcher *matcher;
if (attributes == NULL)
@@ -629,29 +1133,30 @@ g_file_attribute_matcher_new (const char *attributes)
split = g_strsplit (attributes, ",", -1);
- num_ns = 0;
- num_fn = 0;
-
- full_name_array = NULL;
- namespace_array = NULL;
-
for (i = 0; split[i] != NULL; i++)
{
if (strcmp (split[i], "*") == 0)
matcher->all = TRUE;
else
{
+ guint32 id, mask;
+
colon = strchr (split[i], ':');
-
- full_name_q = 0;
if (colon != NULL && colon[1] != 0)
{
- full_name_q = g_quark_from_string (split[i]);
- *colon = 0;
+ id = lookup_attribute (split[i]);
+ mask = 0xffffffff;
+ }
+ else
+ {
+ if (colon)
+ *colon = 0;
+
+ id = lookup_namespace (split[i]) << NS_POS;
+ mask = NS_MASK << NS_POS;
}
- namespace_q = g_quark_from_string (split[i]);
- matcher_add_namespace (matcher, namespace_q, full_name_q);
+ matcher_add (matcher, id, mask);
}
}
@@ -663,52 +1168,21 @@ g_file_attribute_matcher_new (const char *attributes)
void
g_file_attribute_matcher_free (GFileAttributeMatcher *matcher)
{
- NamespaceMatcher *ns_matcher;
- int i;
-
if (matcher == NULL)
return;
-
- for (i = 0; i < ON_STACK_NAMESPACES; i++)
- {
- ns_matcher = &matcher->namespaces[i];
-
- if (ns_matcher->more_full_names != NULL)
- g_array_free (ns_matcher->more_full_names, TRUE);
- }
-
- if (matcher->more_namespaces)
- {
- for (i = 0; i < matcher->more_namespaces->len; i++)
- {
- ns_matcher = &g_array_index (matcher->more_namespaces, NamespaceMatcher, i);
-
- if (ns_matcher->more_full_names != NULL)
- g_array_free (ns_matcher->more_full_names, TRUE);
- }
-
- g_array_free (matcher->more_namespaces, TRUE);
- }
+
+ if (matcher->more_sub_matchers)
+ g_array_free (matcher->more_sub_matchers, TRUE);
g_free (matcher);
}
gboolean
g_file_attribute_matcher_matches (GFileAttributeMatcher *matcher,
- const char *namespace,
- const char *full_name)
+ const char *attribute)
{
- return g_file_attribute_matcher_matches_q (matcher,
- g_quark_from_string (namespace),
- g_quark_from_string (full_name));
-}
-
-gboolean
-g_file_attribute_matcher_matches_q (GFileAttributeMatcher *matcher,
- GQuark namespace,
- GQuark full_name)
-{
- NamespaceMatcher *ns_matcher;
+ SubMatcher *sub_matchers;
+ guint32 id;
int i;
if (matcher == NULL)
@@ -716,111 +1190,103 @@ g_file_attribute_matcher_matches_q (GFileAttributeMatcher *matcher,
if (matcher->all)
return TRUE;
-
- ns_matcher = matcher_find_namespace (matcher, namespace, FALSE);
- if (ns_matcher == NULL)
- return FALSE;
-
- if (ns_matcher->all)
- return TRUE;
+ id = lookup_attribute (attribute);
- for (i = 0; i < ON_STACK_ATTRIBUTES; i++)
+ for (i = 0; i < ON_STACK_MATCHERS; i++)
{
- if (ns_matcher->full_names[i] == 0)
+ if (matcher->sub_matchers[i].id == 0)
return FALSE;
- if (ns_matcher->full_names[i] == full_name)
+ if (matcher->sub_matchers[i].id == (id & matcher->sub_matchers[i].mask))
return TRUE;
}
- if (ns_matcher->more_full_names)
+ if (matcher->more_sub_matchers)
{
- for (i = 0; i < ns_matcher->more_full_names->len; i++)
+ sub_matchers = (SubMatcher *)matcher->more_sub_matchers->data;
+ for (i = 0; i < matcher->more_sub_matchers->len; i++)
{
- GQuark existing_name = g_array_index (ns_matcher->more_full_names, GQuark, i);
- if (existing_name == full_name)
+ if (matcher->sub_matchers[i].id == (id & matcher->sub_matchers[i].mask))
return TRUE;
}
}
-
return FALSE;
}
-
-gboolean
-g_file_attribute_matcher_enumerate (GFileAttributeMatcher *matcher,
- const char *namespace)
-{
- return g_file_attribute_matcher_enumerate_q (matcher,
- g_quark_from_string (namespace));
-}
-
/* return TRUE -> all */
gboolean
-g_file_attribute_matcher_enumerate_q (GFileAttributeMatcher *matcher,
- GQuark namespace)
+g_file_attribute_matcher_enumerate_namespace (GFileAttributeMatcher *matcher,
+ const char *namespace)
{
- NamespaceMatcher *ns_matcher;
-
+ SubMatcher *sub_matchers;
+ int ns_id;
+ int i;
+
if (matcher == NULL)
return FALSE;
if (matcher->all)
return TRUE;
- ns_matcher = matcher_find_namespace (matcher, namespace, FALSE);
+ ns_id = lookup_namespace (namespace) << NS_POS;
- matcher->matched_namespace = ns_matcher;
- matcher->attribute_pos = 0;
-
- if (ns_matcher == NULL)
- return FALSE;
-
- if (ns_matcher->all)
- return TRUE;
+ for (i = 0; i < ON_STACK_MATCHERS; i++)
+ {
+ if (matcher->sub_matchers[i].id == ns_id)
+ return TRUE;
+ }
+
+ if (matcher->more_sub_matchers)
+ {
+ sub_matchers = (SubMatcher *)matcher->more_sub_matchers->data;
+ for (i = 0; i < matcher->more_sub_matchers->len; i++)
+ {
+ if (matcher->sub_matchers[i].id == ns_id)
+ return TRUE;
+ }
+ }
+ matcher->iterator_ns = ns_id;
+ matcher->iterator_pos = 0;
+
return FALSE;
}
-const char *
+const const char *
g_file_attribute_matcher_enumerate_next (GFileAttributeMatcher *matcher)
{
- NamespaceMatcher *ns_matcher;
int i;
- GQuark full_name_q;
- const char *full_name;
+ SubMatcher *sub_matcher;
if (matcher == NULL)
return NULL;
- ns_matcher = matcher->matched_namespace;
-
- if (ns_matcher == NULL)
- return NULL;
+ while (1)
+ {
+ i = matcher->iterator_pos++;
- i = matcher->attribute_pos++;
+ if (i < ON_STACK_MATCHERS)
+ {
+ if (matcher->sub_matchers[i].id == 0)
+ return NULL;
- if (i < ON_STACK_ATTRIBUTES)
- {
- full_name_q = ns_matcher->full_names[i];
- if (full_name_q == 0)
- return NULL;
- }
- else
- {
- if (ns_matcher->more_full_names == NULL)
- return NULL;
-
- i -= ON_STACK_ATTRIBUTES;
- if (i < ns_matcher->more_full_names->len)
- full_name_q = g_array_index (ns_matcher->more_full_names, GQuark, i);
+ sub_matcher = &matcher->sub_matchers[i];
+ }
else
- return NULL;
- }
-
- full_name = g_quark_to_string (full_name_q);
+ {
+ if (matcher->more_sub_matchers == NULL)
+ return NULL;
+
+ i -= ON_STACK_MATCHERS;
+ if (i < matcher->more_sub_matchers->len)
+ sub_matcher = &g_array_index (matcher->more_sub_matchers, SubMatcher, i);
+ else
+ return NULL;
+ }
- /* Full names are guaranteed to have a ':' in them */
- return strchr (full_name, ':') + 1;
+ if (sub_matcher->mask == 0xffffffff &&
+ (sub_matcher->id & (NS_MASK << NS_POS)) == matcher->iterator_ns)
+ return get_attribute_for_id (sub_matcher->id);
+ }
}
diff --git a/gio/gfileinfo.h b/gio/gfileinfo.h
index 42b0831b..b37c14f1 100644
--- a/gio/gfileinfo.h
+++ b/gio/gfileinfo.h
@@ -1,8 +1,6 @@
#ifndef __G_FILE_INFO_H__
#define __G_FILE_INFO_H__
-#include <sys/stat.h>
-
#include <glib-object.h>
#include <gio/gvfstypes.h>
@@ -17,8 +15,6 @@ G_BEGIN_DECLS
typedef struct _GFileInfo GFileInfo;
typedef struct _GFileInfoClass GFileInfoClass;
-typedef struct _GFileInfoPrivate GFileInfoPrivate;
-typedef struct _GFileAttribute GFileAttribute;
typedef struct _GFileAttributeMatcher GFileAttributeMatcher;
typedef enum {
@@ -39,114 +35,160 @@ typedef enum {
G_FILE_ACCESS_CAN_RENAME = 1 << 5,
} GFileAccessRights;
-struct _GFileInfo
-{
- GObject parent_instance;
+typedef enum {
+ G_FILE_ATTRIBUTE_TYPE_INVALID = 0,
+ G_FILE_ATTRIBUTE_TYPE_STRING,
+ G_FILE_ATTRIBUTE_TYPE_BYTE_STRING,
+ G_FILE_ATTRIBUTE_TYPE_UINT32,
+ G_FILE_ATTRIBUTE_TYPE_INT32,
+ G_FILE_ATTRIBUTE_TYPE_UINT64,
+ G_FILE_ATTRIBUTE_TYPE_INT64
+} GFileAttributeType;
- GFileInfoPrivate *priv;
-};
+typedef enum {
+ G_FILE_FLAG_HIDDEN = (1<<0),
+ G_FILE_FLAG_SYMLINK = (1<<1),
+ G_FILE_FLAG_LOCAL = (1<<2),
+ G_FILE_FLAG_VIRTUAL = (1<<3),
+} GFileFlags;
struct _GFileInfoClass
{
GObjectClass parent_class;
};
-struct _GFileAttribute {
- const char *attribute;
- const char *value;
-};
-
-typedef enum {
- G_FILE_INFO_FILE_TYPE = 1 << 0,
- G_FILE_INFO_NAME = 1 << 1,
- G_FILE_INFO_DISPLAY_NAME = 1 << 2,
- G_FILE_INFO_EDIT_NAME = 1 << 3,
- G_FILE_INFO_ICON = 1 << 4,
- G_FILE_INFO_MIME_TYPE = 1 << 5,
- G_FILE_INFO_SIZE = 1 << 6,
- G_FILE_INFO_MODIFICATION_TIME = 1 << 7,
- G_FILE_INFO_ACCESS_RIGHTS = 1 << 8,
- G_FILE_INFO_STAT_INFO = 1 << 9,
- G_FILE_INFO_SYMLINK_TARGET = 1 << 10,
- G_FILE_INFO_IS_HIDDEN = 1 << 11,
-} GFileInfoRequestFlags;
-
-#define G_FILE_INFO_REQUEST_FLAGS_FROM_STAT_MASK (G_FILE_INFO_FILE_TYPE | G_FILE_INFO_SIZE | G_FILE_INFO_MODIFICATION_TIME | G_FILE_INFO_STAT_INFO)
+/* Common Attributes: */
+
+#define G_FILE_ATTRIBUTE_STD_TYPE "std:type"
+#define G_FILE_ATTRIBUTE_STD_FLAGS "std:flags"
+#define G_FILE_ATTRIBUTE_STD_NAME "std:name"
+#define G_FILE_ATTRIBUTE_STD_DISPLAY_NAME "std:display_name"
+#define G_FILE_ATTRIBUTE_STD_EDIT_NAME "std:edit_name"
+#define G_FILE_ATTRIBUTE_STD_ICON "std:icon"
+#define G_FILE_ATTRIBUTE_STD_MIME_TYPE "std:mime_type"
+#define G_FILE_ATTRIBUTE_STD_SIZE "std:size"
+#define G_FILE_ATTRIBUTE_STD_SYMLINK_TARGET "std:symlink_target"
+#define G_FILE_ATTRIBUTE_STD_ACCESS_RIGHTS "std:access_rights"
+#define G_FILE_ATTRIBUTE_STD_ACCESS_RIGHTS_MASK "std:access_rights_mask"
+#define G_FILE_ATTRIBUTE_STD_MTIME "std:mtime"
+#define G_FILE_ATTRIBUTE_STD_MTIME_USEC "std:mtime_usec"
+
+/* Unix specific attributes */
+
+#define G_FILE_ATTRIBUTE_UNIX_DEVICE "unix:device"
+#define G_FILE_ATTRIBUTE_UNIX_INODE "unix:inode"
+#define G_FILE_ATTRIBUTE_UNIX_MODE "unix:mode"
+#define G_FILE_ATTRIBUTE_UNIX_NLINK "unix:nlink"
+#define G_FILE_ATTRIBUTE_UNIX_UID "unix:uid"
+#define G_FILE_ATTRIBUTE_UNIX_GID "unix:gid"
+#define G_FILE_ATTRIBUTE_UNIX_RDEV "unix:rdev"
+#define G_FILE_ATTRIBUTE_UNIX_BLOCK_SIZE "unix:block_size"
+#define G_FILE_ATTRIBUTE_UNIX_BLOCKS "unix:blocks"
+#define G_FILE_ATTRIBUTE_UNIX_ATIME "unix:atime"
+#define G_FILE_ATTRIBUTE_UNIX_ATIME_USEC "unix:atime_usec"
+#define G_FILE_ATTRIBUTE_UNIX_CTIME "unix:ctime"
+#define G_FILE_ATTRIBUTE_UNIX_CTIME_USEC "unix:ctime_usec"
+
+/* Owner attributes */
+
+#define G_FILE_ATTRIBUTE_OWNER_USER "owner:user"
+#define G_FILE_ATTRIBUTE_OWNER_GROUP "owner:group"
GType g_file_info_get_type (void) G_GNUC_CONST;
-
-GFileInfo * g_file_info_new (void);
-GFileType g_file_info_get_file_type (GFileInfo *info);
-const char * g_file_info_get_name (GFileInfo *info);
-const char * g_file_info_get_display_name (GFileInfo *info);
-const char * g_file_info_get_edit_name (GFileInfo *info);
-const char * g_file_info_get_icon (GFileInfo *info);
-const char * g_file_info_get_mime_type (GFileInfo *info);
-GQuark g_file_info_get_mime_type_quark (GFileInfo *info);
-goffset g_file_info_get_size (GFileInfo *info);
-time_t g_file_info_get_modification_time (GFileInfo *info);
-const char * g_file_info_get_symlink_target (GFileInfo *info);
-GFileAccessRights g_file_info_get_access_rights (GFileInfo *info);
-gboolean g_file_info_can_read (GFileInfo *info);
-gboolean g_file_info_can_write (GFileInfo *info);
-gboolean g_file_info_can_delete (GFileInfo *info);
-gboolean g_file_info_can_rename (GFileInfo *info);
-gboolean g_file_info_get_is_hidden (GFileInfo *info);
-const struct stat * g_file_info_get_stat_info (GFileInfo *info);
-const char * g_file_info_get_attribute (GFileInfo *info,
- const char *attribute);
-GFileAttribute * g_file_info_get_attributes (GFileInfo *info,
- const char *namespace,
- int *n_attributes);
-GFileAttribute * g_file_info_get_all_attributes (GFileInfo *info,
- int *n_attributes);
-void g_file_info_set_file_type (GFileInfo *info,
- GFileType type);
-void g_file_info_set_name (GFileInfo *info,
- const char *name);
-void g_file_info_set_display_name (GFileInfo *info,
- const char *display_name);
-void g_file_info_set_edit_name (GFileInfo *info,
- const char *edit_name);
-void g_file_info_set_icon (GFileInfo *info,
- const char *icon);
-void g_file_info_set_mime_type (GFileInfo *info,
- const char *mime_type);
-void g_file_info_set_size (GFileInfo *info,
- goffset size);
-void g_file_info_set_modification_time (GFileInfo *info,
- time_t time);
-void g_file_info_set_symlink_target (GFileInfo *info,
- const char *link_target);
-void g_file_info_set_access_rights (GFileInfo *info,
- GFileAccessRights access_rights);
-void g_file_info_set_is_hidden (GFileInfo *info,
- gboolean is_hidden);
-void g_file_info_set_stat_info (GFileInfo *info,
- const struct stat *statbuf);
-void g_file_info_set_attribute (GFileInfo *info,
- const char *attribute,
- const char *value);
-void g_file_info_set_attributes (GFileInfo *info,
- GFileAttribute *attributes,
- int n_attributes);
-
-void g_file_info_set_from_stat (GFileInfo *info,
- GFileInfoRequestFlags requested,
- const struct stat *statbuf);
+
+GFileInfo * g_file_info_new (void);
+GFileInfo * g_file_info_copy (GFileInfo *info);
+gboolean g_file_info_has_attribute (GFileInfo *info,
+ const char *attribute);
+char ** g_file_info_list_attributes (GFileInfo *info,
+ const char *name_space);
+GFileAttributeType g_file_info_get_attribute_type (GFileInfo *info,
+ const char *attribute);
+void g_file_info_remove_attribute (GFileInfo *info,
+ const char *attribute);
+char * g_file_info_get_attribute_as_string (GFileInfo *info,
+ const char *attribute);
+const char * g_file_info_get_attribute_string (GFileInfo *info,
+ const char *attribute);
+const char * g_file_info_get_attribute_byte_string (GFileInfo *info,
+ const char *attribute);
+guint32 g_file_info_get_attribute_uint32 (GFileInfo *info,
+ const char *attribute);
+gint32 g_file_info_get_attribute_int32 (GFileInfo *info,
+ const char *attribute);
+guint64 g_file_info_get_attribute_uint64 (GFileInfo *info,
+ const char *attribute);
+gint64 g_file_info_get_attribute_int64 (GFileInfo *info,
+ const char *attribute);
+void g_file_info_set_attribute_string (GFileInfo *info,
+ const char *attribute,
+ const char *value);
+void g_file_info_set_attribute_byte_string (GFileInfo *info,
+ const char *attribute,
+ const char *value);
+void g_file_info_set_attribute_uint32 (GFileInfo *info,
+ const char *attribute,
+ guint32 value);
+void g_file_info_set_attribute_int32 (GFileInfo *info,
+ const char *attribute,
+ gint32 value);
+void g_file_info_set_attribute_uint64 (GFileInfo *info,
+ const char *attribute,
+ guint64 value);
+void g_file_info_set_attribute_int64 (GFileInfo *info,
+ const char *attribute,
+ gint64 value);
+
+
+/* Helper getters: */
+GFileType g_file_info_get_file_type (GFileInfo *info);
+GFileFlags g_file_info_get_flags (GFileInfo *info);
+const char * g_file_info_get_name (GFileInfo *info);
+const char * g_file_info_get_display_name (GFileInfo *info);
+const char * g_file_info_get_edit_name (GFileInfo *info);
+const char * g_file_info_get_icon (GFileInfo *info);
+const char * g_file_info_get_mime_type (GFileInfo *info);
+goffset g_file_info_get_size (GFileInfo *info);
+void g_file_info_get_modification_time (GFileInfo *info,
+ GTimeVal *result);
+const char * g_file_info_get_symlink_target (GFileInfo *info);
+GFileAccessRights g_file_info_get_access_rights (GFileInfo *info);
+GFileAccessRights g_file_info_get_access_rights_mask (GFileInfo *info);
+
+
+/* Helper setters: */
+void g_file_info_set_file_type (GFileInfo *info,
+ GFileType type);
+void g_file_info_set_flags (GFileInfo *info,
+ GFileFlags flags);
+void g_file_info_set_name (GFileInfo *info,
+ const char *name);
+void g_file_info_set_display_name (GFileInfo *info,
+ const char *display_name);
+void g_file_info_set_edit_name (GFileInfo *info,
+ const char *edit_name);
+void g_file_info_set_icon (GFileInfo *info,
+ const char *icon);
+void g_file_info_set_mime_type (GFileInfo *info,
+ const char *mime_type);
+void g_file_info_set_size (GFileInfo *info,
+ goffset size);
+void g_file_info_set_modification_time (GFileInfo *info,
+ GTimeVal *mtime);
+void g_file_info_set_symlink_target (GFileInfo *info,
+ const char *symlink_target);
+void g_file_info_set_access_rights (GFileInfo *info,
+ GFileAccessRights rights);
+void g_file_info_set_access_rights_mask (GFileInfo *info,
+ GFileAccessRights mask);
+
GFileAttributeMatcher *g_file_attribute_matcher_new (const char *attributes);
void g_file_attribute_matcher_free (GFileAttributeMatcher *matcher);
gboolean g_file_attribute_matcher_matches (GFileAttributeMatcher *matcher,
- const char *namespace,
const char *full_name);
-gboolean g_file_attribute_matcher_matches_q (GFileAttributeMatcher *matcher,
- GQuark namespace,
- GQuark full_name);
-gboolean g_file_attribute_matcher_enumerate (GFileAttributeMatcher *matcher,
- const char *namespace);
-gboolean g_file_attribute_matcher_enumerate_q (GFileAttributeMatcher *matcher,
- GQuark namespace);
+gboolean g_file_attribute_matcher_enumerate_namespace (GFileAttributeMatcher *matcher,
+ const char *namespace);
const char * g_file_attribute_matcher_enumerate_next (GFileAttributeMatcher *matcher);
G_END_DECLS
diff --git a/gio/gfileinfolocal.c b/gio/gfileinfolocal.c
index 6dbd0eba..858f9b69 100644
--- a/gio/gfileinfolocal.c
+++ b/gio/gfileinfolocal.c
@@ -65,8 +65,7 @@ get_selinux_context (const char *path,
#ifdef HAVE_SELINUX
char *context;
- if (!g_file_attribute_matcher_matches (attribute_matcher,
- "selinux", "selinux:context"))
+ if (!g_file_attribute_matcher_matches (attribute_matcher, "selinux:context"))
return;
if (is_selinux_enabled ())
@@ -84,7 +83,7 @@ get_selinux_context (const char *path,
if (context)
{
- g_file_info_set_attribute (info, "selinux:context", context);
+ g_file_info_set_attribute_string (info, "selinux:context", context);
freecon(context);
}
}
@@ -121,7 +120,7 @@ escape_xattr (GFileInfo *info,
}
if (num_invalid == 0)
- g_file_info_set_attribute (info, full_attr, value);
+ g_file_info_set_attribute_string (info, full_attr, value);
else
{
escaped_val = g_malloc (len + num_invalid*3 + 1);
@@ -141,7 +140,7 @@ escape_xattr (GFileInfo *info,
}
}
*p++ = 0;
- g_file_info_set_attribute (info, full_attr, escaped_val);
+ g_file_info_set_attribute_string (info, full_attr, escaped_val);
g_free (escaped_val);
}
@@ -217,7 +216,7 @@ get_xattrs (const char *path,
char *list;
const char *attr;
- all = g_file_attribute_matcher_enumerate (matcher, "xattr");
+ all = g_file_attribute_matcher_enumerate_namespace (matcher, "xattr");
if (all)
{
@@ -327,7 +326,7 @@ get_xattrs_from_fd (int fd,
char *list;
const char *attr;
- all = g_file_attribute_matcher_enumerate (matcher, "xattr");
+ all = g_file_attribute_matcher_enumerate_namespace (matcher, "xattr");
if (all)
{
@@ -425,40 +424,90 @@ get_access_rights (const gchar *path)
return rights;
}
+static void
+set_info_from_stat (GFileInfo *info, struct stat *statbuf)
+{
+ GFileType file_type;
+ GTimeVal t;
+
+ file_type = G_FILE_TYPE_UNKNOWN;
+
+ if (S_ISREG (statbuf->st_mode))
+ file_type = G_FILE_TYPE_REGULAR;
+ else if (S_ISDIR (statbuf->st_mode))
+ file_type = G_FILE_TYPE_DIRECTORY;
+ else if (S_ISCHR (statbuf->st_mode) ||
+ S_ISBLK (statbuf->st_mode) ||
+ S_ISFIFO (statbuf->st_mode)
+#ifdef S_ISSOCK
+ || S_ISSOCK (statbuf->st_mode)
+#endif
+ )
+ file_type = G_FILE_TYPE_SPECIAL;
+ else if (S_ISLNK (statbuf->st_mode))
+ file_type = G_FILE_TYPE_SYMBOLIC_LINK;
+
+ g_file_info_set_file_type (info, file_type);
+ g_file_info_set_size (info, statbuf->st_size);
+
+ t.tv_sec = statbuf->st_mtime;
+#if defined (HAVE_STRUCT_STAT_ST_MTIMENSEC)
+ t.tv_usec = statbuf->st_mtimensec / 1000;
+#elif defined (HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+ t.tv_usec = statbuf->st_mtim.tv_nsec / 1000;
+#else
+ t.tv_usec = 0;
+#endif
+ g_file_info_set_modification_time (info, &t);
+
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_DEVICE, statbuf->st_dev);
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_INODE, statbuf->st_ino);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE, statbuf->st_mode);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_NLINK, statbuf->st_nlink);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID, statbuf->st_uid);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID, statbuf->st_uid);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_RDEV, statbuf->st_rdev);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_BLOCK_SIZE, statbuf->st_blksize);
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_BLOCKS, statbuf->st_blocks);
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_ATIME, statbuf->st_atime);
+#if defined (HAVE_STRUCT_STAT_ST_ATIMENSEC)
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_ATIME_USEC, statbuf->st_atimensec / 1000);
+#elif defined (HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC)
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_ATIME_USEC, statbuf->st_atim.tv_nsec / 1000);
+#endif
+ g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_CTIME, statbuf->st_ctime);
+#if defined (HAVE_STRUCT_STAT_ST_CTIMENSEC)
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_CTIME_USEC, statbuf->st_ctimensec / 1000);
+#elif defined (HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC)
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_CTIME_USEC, statbuf->st_ctim.tv_nsec / 1000);
+#endif
+}
GFileInfo *
g_file_info_local_get (const char *basename,
const char *path,
- GFileInfoRequestFlags requested,
GFileAttributeMatcher *attribute_matcher,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GError **error)
{
GFileInfo *info;
struct stat statbuf;
+ struct stat statbuf2;
int res;
+ GFileFlags file_flags;
+ gboolean is_symlink;
info = g_file_info_new ();
-
- if (requested & G_FILE_INFO_NAME)
- g_file_info_set_name (info, basename);
-
- if (requested & G_FILE_INFO_IS_HIDDEN)
- g_file_info_set_is_hidden (info,
- basename != NULL &&
- basename[0] == '.');
+ file_flags = 0;
+
+ g_file_info_set_name (info, basename);
/* Avoid stat in trivial case */
- if ((requested & ~(G_FILE_INFO_NAME|G_FILE_INFO_IS_HIDDEN)) == 0 &&
- attribute_matcher == NULL)
+ if (attribute_matcher == NULL)
return info;
-
- if (follow_symlinks)
- res = stat (path, &statbuf);
- else
- res = lstat (path, &statbuf);
-
+
+ res = g_lstat (path, &statbuf);
if (res == -1)
{
g_object_unref (info);
@@ -468,23 +517,54 @@ g_file_info_local_get (const char *basename,
path, g_strerror (errno));
return NULL;
}
+
+ is_symlink = S_ISLNK (statbuf.st_mode);
- g_file_info_set_from_stat (info, requested, &statbuf);
+ if (is_symlink)
+ {
+ file_flags |= G_FILE_FLAG_SYMLINK;
+
+ /* Unless NOFOLLOW was set we default to following symlinks */
+ if (!(flags & G_FILE_GET_INFO_NOFOLLOW_SYMLINKS))
+ {
+ res = stat (path, &statbuf2);
+
+ /* Report broken links as symlinks */
+ if (res != -1)
+ statbuf = statbuf2;
+ }
+ }
+
+ set_info_from_stat (info, &statbuf);
- if (requested & G_FILE_INFO_SYMLINK_TARGET)
+ if (basename != NULL && basename[0] == '.')
+ file_flags |= G_FILE_FLAG_HIDDEN;
+
+ g_file_info_set_flags (info, file_flags);
+
+ if (is_symlink &&
+ g_file_attribute_matcher_matches (attribute_matcher,
+ G_FILE_ATTRIBUTE_STD_SYMLINK_TARGET))
{
char *link = read_link (path);
g_file_info_set_symlink_target (info, link);
g_free (link);
}
- if (requested & G_FILE_INFO_ACCESS_RIGHTS)
+ if (g_file_attribute_matcher_matches (attribute_matcher,
+ G_FILE_ATTRIBUTE_STD_ACCESS_RIGHTS))
{
GFileAccessRights rights = get_access_rights (path);
g_file_info_set_access_rights (info, rights);
+ /* TODO: Figure out DELETE and RENAME rights */
+ g_file_info_set_access_rights_mask (info,
+ G_FILE_ACCESS_CAN_READ |
+ G_FILE_ACCESS_CAN_WRITE |
+ G_FILE_ACCESS_CAN_EXECUTE);
}
- if (requested & G_FILE_INFO_DISPLAY_NAME)
+ if (g_file_attribute_matcher_matches (attribute_matcher,
+ G_FILE_ATTRIBUTE_STD_DISPLAY_NAME))
{
char *display_name = g_filename_display_basename (path);
@@ -498,32 +578,34 @@ g_file_info_local_get (const char *basename,
g_free (display_name);
}
- if (requested & G_FILE_INFO_EDIT_NAME)
+ if (g_file_attribute_matcher_matches (attribute_matcher,
+ G_FILE_ATTRIBUTE_STD_EDIT_NAME))
{
char *edit_name = g_filename_display_basename (path);
g_file_info_set_edit_name (info, edit_name);
g_free (edit_name);
}
- if (requested & G_FILE_INFO_MIME_TYPE)
+ if (g_file_attribute_matcher_matches (attribute_matcher,
+ G_FILE_ATTRIBUTE_STD_MIME_TYPE))
{
/* TODO */
}
- if (requested & G_FILE_INFO_ICON)
+ if (g_file_attribute_matcher_matches (attribute_matcher,
+ G_FILE_ATTRIBUTE_STD_ICON))
{
/* TODO */
}
- get_selinux_context (path, info, attribute_matcher, follow_symlinks);
- get_xattrs (path, info, attribute_matcher, follow_symlinks);
+ get_selinux_context (path, info, attribute_matcher, (flags & G_FILE_GET_INFO_NOFOLLOW_SYMLINKS) == 0);
+ get_xattrs (path, info, attribute_matcher, (flags & G_FILE_GET_INFO_NOFOLLOW_SYMLINKS) == 0);
return info;
}
GFileInfo *
g_file_info_local_get_from_fd (int fd,
- GFileInfoRequestFlags requested,
char *attributes,
GError **error)
{
@@ -541,19 +623,19 @@ g_file_info_local_get_from_fd (int fd,
}
info = g_file_info_new ();
-
- g_file_info_set_from_stat (info, requested, &stat_buf);
+ set_info_from_stat (info, &stat_buf);
+
matcher = g_file_attribute_matcher_new (attributes);
#ifdef HAVE_SELINUX
- if (g_file_attribute_matcher_matches (matcher, "selinux", "selinux:context") &&
+ if (g_file_attribute_matcher_matches (matcher, "selinux:context") &&
is_selinux_enabled ())
{
char *context;
if (fgetfilecon_raw (fd, &context) >= 0)
{
- g_file_info_set_attribute (info, "selinux:context", context);
+ g_file_info_set_attribute_string (info, "selinux:context", context);
freecon(context);
}
}
diff --git a/gio/gfileinfolocal.h b/gio/gfileinfolocal.h
index 37c54987..25163f7b 100644
--- a/gio/gfileinfolocal.h
+++ b/gio/gfileinfolocal.h
@@ -2,17 +2,16 @@
#define __G_FILE_INFO_LOCAL_H__
#include <gio/gfileinfo.h>
+#include <gio/gfile.h>
G_BEGIN_DECLS
GFileInfo *g_file_info_local_get (const char *basename,
const char *path,
- GFileInfoRequestFlags requested,
GFileAttributeMatcher *attribute_matcher,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GError **error);
GFileInfo *g_file_info_local_get_from_fd (int fd,
- GFileInfoRequestFlags requested,
char *attributes,
GError **error);
diff --git a/gio/gfileinputstream.c b/gio/gfileinputstream.c
index 8cef6560..3e01fcae 100644
--- a/gio/gfileinputstream.c
+++ b/gio/gfileinputstream.c
@@ -53,7 +53,6 @@ g_file_input_stream_init (GFileInputStream *stream)
GFileInfo *
g_file_input_stream_get_file_info (GFileInputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error)
@@ -90,7 +89,7 @@ g_file_input_stream_get_file_info (GFileInputStream *stream,
class = G_FILE_INPUT_STREAM_GET_CLASS (stream);
if (class->get_file_info)
- info = class->get_file_info (stream, requested, attributes, cancellable, error);
+ info = class->get_file_info (stream, attributes, cancellable, error);
else
g_set_error (error, G_VFS_ERROR, G_VFS_ERROR_NOT_SUPPORTED,
_("Stream doesn't support get_file_info"));
diff --git a/gio/gfileinputstream.h b/gio/gfileinputstream.h
index 6d7f46ee..42b7295b 100644
--- a/gio/gfileinputstream.h
+++ b/gio/gfileinputstream.h
@@ -37,7 +37,6 @@ struct _GFileInputStreamClass
GCancellable *cancellable,
GError **error);
GFileInfo *(*get_file_info) (GFileInputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error);
@@ -54,7 +53,6 @@ GType g_file_input_stream_get_type (void) G_GNUC_CONST;
/* TODO: Turn this into a interface like GSeekable? */
GFileInfo *g_file_input_stream_get_file_info (GFileInputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error);
diff --git a/gio/gfileinputstreamlocal.c b/gio/gfileinputstreamlocal.c
index b60336a6..2b192a0a 100644
--- a/gio/gfileinputstreamlocal.c
+++ b/gio/gfileinputstreamlocal.c
@@ -33,7 +33,6 @@ static gboolean g_file_input_stream_local_close (GInputStream
GCancellable *cancellable,
GError **error);
static GFileInfo *g_file_input_stream_local_get_file_info (GFileInputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error);
@@ -199,7 +198,6 @@ g_file_input_stream_local_close (GInputStream *stream,
static GFileInfo *
g_file_input_stream_local_get_file_info (GFileInputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error)
@@ -218,7 +216,6 @@ g_file_input_stream_local_get_file_info (GFileInputStream *stream,
}
return g_file_info_local_get_from_fd (file->priv->fd,
- requested,
attributes,
error);
}
diff --git a/gio/gfilelocal.c b/gio/gfilelocal.c
index 812a906b..19dc69f5 100644
--- a/gio/gfilelocal.c
+++ b/gio/gfilelocal.c
@@ -236,24 +236,21 @@ g_file_local_get_child (GFile *file,
static GFileEnumerator *
g_file_local_enumerate_children (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error)
{
GFileLocal *local = G_FILE_LOCAL (file);
return g_file_enumerator_local_new (local->filename,
- requested, attributes,
- follow_symlinks,
+ attributes, flags,
cancellable, error);
}
static GFileInfo *
g_file_local_get_info (GFile *file,
- GFileInfoRequestFlags requested,
const char *attributes,
- gboolean follow_symlinks,
+ GFileGetInfoFlags flags,
GCancellable *cancellable,
GError **error)
{
@@ -267,8 +264,8 @@ g_file_local_get_info (GFile *file,
basename = g_path_get_basename (local->filename);
info = g_file_info_local_get (basename, local->filename,
- requested, matcher, follow_symlinks,
- error);
+ matcher, flags,
+ error);
g_free (basename);
diff --git a/gio/gfileoutputstream.c b/gio/gfileoutputstream.c
index fed7ebdc..d456e54f 100644
--- a/gio/gfileoutputstream.c
+++ b/gio/gfileoutputstream.c
@@ -8,7 +8,7 @@ G_DEFINE_TYPE (GFileOutputStream, g_file_output_stream, G_TYPE_OUTPUT_STREAM);
struct _GFileOutputStreamPrivate {
guint get_final_mtime : 1;
- time_t final_mtime;
+ GTimeVal final_mtime;
};
static void
@@ -27,7 +27,6 @@ g_file_output_stream_init (GFileOutputStream *stream)
GFileInfo *
g_file_output_stream_get_file_info (GFileOutputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error)
@@ -64,7 +63,7 @@ g_file_output_stream_get_file_info (GFileOutputStream *stream,
class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
if (class->get_file_info)
- info = class->get_file_info (stream, requested, attributes, cancellable, error);
+ info = class->get_file_info (stream, attributes, cancellable, error);
else
g_set_error (error, G_VFS_ERROR, G_VFS_ERROR_NOT_SUPPORTED,
_("Stream doesn't support get_file_info"));
@@ -96,21 +95,22 @@ g_file_output_stream_get_should_get_final_mtime (GFileOutputStream *stream)
return stream->priv->get_final_mtime;
}
-time_t
-g_file_output_stream_get_final_mtime (GFileOutputStream *stream)
+void
+g_file_output_stream_get_final_mtime (GFileOutputStream *stream,
+ GTimeVal *final_mtime)
{
- g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), FALSE);
- g_return_val_if_fail (stream != NULL, FALSE);
+ g_return_if_fail (G_IS_FILE_OUTPUT_STREAM (stream));
+ g_return_if_fail (stream != NULL);
- return stream->priv->final_mtime;
+ *final_mtime = stream->priv->final_mtime;
}
void
g_file_output_stream_set_final_mtime (GFileOutputStream *stream,
- time_t final_mtime)
+ GTimeVal *final_mtime)
{
g_return_if_fail (G_IS_FILE_OUTPUT_STREAM (stream));
g_return_if_fail (stream != NULL);
- stream->priv->final_mtime = final_mtime;
+ stream->priv->final_mtime = *final_mtime;
}
diff --git a/gio/gfileoutputstream.h b/gio/gfileoutputstream.h
index 9c3b67e3..69ab2a88 100644
--- a/gio/gfileoutputstream.h
+++ b/gio/gfileoutputstream.h
@@ -37,7 +37,6 @@ struct _GFileOutputStreamClass
GCancellable *cancellable,
GError **error);
GFileInfo *(*get_file_info) (GFileOutputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error);
@@ -54,16 +53,16 @@ GType g_file_output_stream_get_type (void) G_GNUC_CONST;
GFileInfo *g_file_output_stream_get_file_info (GFileOutputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error);
void g_file_output_stream_set_should_get_final_mtime (GFileOutputStream *stream,
gboolean get_final_mtime);
-time_t g_file_output_stream_get_final_mtime (GFileOutputStream *stream);
+void g_file_output_stream_get_final_mtime (GFileOutputStream *stream,
+ GTimeVal *mtime);
gboolean g_file_output_stream_get_should_get_final_mtime (GFileOutputStream *stream);
void g_file_output_stream_set_final_mtime (GFileOutputStream *stream,
- time_t final_mtime);
+ GTimeVal *final_mtime);
G_END_DECLS
diff --git a/gio/gfileoutputstreamlocal.c b/gio/gfileoutputstreamlocal.c
index 44fbf83c..79aa10fa 100644
--- a/gio/gfileoutputstreamlocal.c
+++ b/gio/gfileoutputstreamlocal.c
@@ -38,7 +38,6 @@ static gboolean g_file_output_stream_local_close (GOutputStream
GCancellable *cancellable,
GError **error);
static GFileInfo *g_file_output_stream_local_get_file_info (GFileOutputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error);
@@ -195,8 +194,19 @@ g_file_output_stream_local_close (GOutputStream *stream,
}
if (fstat (file->priv->fd, &final_stat) == 0)
- g_file_output_stream_set_final_mtime (G_FILE_OUTPUT_STREAM (stream),
- final_stat.st_mtime);
+ {
+ GTimeVal tv;
+ tv.tv_sec = final_stat.st_mtime;
+#if defined (HAVE_STRUCT_STAT_ST_MTIMENSEC)
+ tv.tv_usec = final_stat.st_mtimensec / 1000;
+#elif defined (HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+ tv.tv_usec = final_stat.st_mtim.tv_nsec / 1000;
+#else
+ tv.tv_usec = 0;
+#endif
+ g_file_output_stream_set_final_mtime (G_FILE_OUTPUT_STREAM (stream),
+ &tv);
+ }
}
while (1)
@@ -222,7 +232,6 @@ g_file_output_stream_local_close (GOutputStream *stream,
static GFileInfo *
g_file_output_stream_local_get_file_info (GFileOutputStream *stream,
- GFileInfoRequestFlags requested,
char *attributes,
GCancellable *cancellable,
GError **error)
@@ -241,7 +250,6 @@ g_file_output_stream_local_get_file_info (GFileOutputStream *stream,
}
return g_file_info_local_get_from_fd (file->priv->fd,
- requested,
attributes,
error);
}
diff --git a/programs/gvfs-info.c b/programs/gvfs-info.c
index 3c1578c3..00cbe7ec 100644
--- a/programs/gvfs-info.c
+++ b/programs/gvfs-info.c
@@ -5,12 +5,12 @@
#include <gio/gfile.h>
static char *attributes = NULL;
-static gboolean follow_symlinks = FALSE;
+static gboolean nofollow_symlinks = FALSE;
static GOptionEntry entries[] =
{
{ "attributes", 'a', 0, G_OPTION_ARG_STRING, &attributes, "The attributes to get", NULL },
- { "follow-symlinks", 'f', 0, G_OPTION_ARG_NONE, &follow_symlinks, "Follow symlinks", NULL },
+ { "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, "Don't follow symlinks", NULL },
{ NULL }
};
@@ -77,8 +77,8 @@ show_info (GFileInfo *info)
const char *name, *type;
char *escaped;
goffset size;
- GFileAttribute *attributes;
- int n_attributes, i;
+ char **attributes;
+ int i;
name = g_file_info_get_display_name (info);
if (name)
@@ -102,37 +102,41 @@ show_info (GFileInfo *info)
size = g_file_info_get_size (info);
g_print ("size: %"G_GUINT64_FORMAT"\n", (guint64)size);
- if (g_file_info_get_is_hidden (info))
+ if (g_file_info_get_flags (info) & G_FILE_FLAG_HIDDEN)
g_print ("hidden\n");
- attributes = g_file_info_get_all_attributes (info, &n_attributes);
+ attributes = g_file_info_list_attributes (info, NULL);
- if (attributes != NULL)
+ g_print ("attributes:\n");
+ for (i = 0; attributes[i] != NULL; i++)
{
- g_print ("attributes:\n");
- for (i = 0; i < n_attributes; i++)
- g_print (" %s: %s\n", attributes[i].attribute, attributes[i].value);
- g_free (attributes);
+ char *value;
+ value = g_file_info_get_attribute_as_string (info, attributes[i]);
+ g_print (" %s: %s\n", attributes[i], value);
+ g_free (value);
}
+ g_strfreev (attributes);
}
static void
get_info (GFile *file)
{
- GFileInfoRequestFlags request;
+ GFileGetInfoFlags flags;
GFileInfo *info;
GError *error;
if (file == NULL)
return;
- request =
- G_FILE_INFO_FILE_TYPE | G_FILE_INFO_NAME |
- G_FILE_INFO_SIZE | G_FILE_INFO_IS_HIDDEN |
- G_FILE_INFO_DISPLAY_NAME | G_FILE_INFO_EDIT_NAME;
+ if (attributes == NULL)
+ attributes = "*";
+
+ flags = 0;
+ if (nofollow_symlinks)
+ flags |= G_FILE_GET_INFO_NOFOLLOW_SYMLINKS;
error = NULL;
- info = g_file_get_info (file, request, attributes, follow_symlinks, NULL, &error);
+ info = g_file_get_info (file, attributes, flags, NULL, &error);
if (info == NULL)
{
diff --git a/programs/gvfs-ls.c b/programs/gvfs-ls.c
index 59ed1d1b..81d965d8 100644
--- a/programs/gvfs-ls.c
+++ b/programs/gvfs-ls.c
@@ -51,7 +51,7 @@ show_info (GFileInfo *info)
const char *name, *type;
goffset size;
- if (g_file_info_get_is_hidden (info) && !show_hidden)
+ if ((g_file_info_get_flags (info) & G_FILE_FLAG_HIDDEN) && !show_hidden)
return;
name = g_file_info_get_name (info);
@@ -66,18 +66,18 @@ show_info (GFileInfo *info)
static void
list (GFile *file)
{
- GFileInfoRequestFlags request;
GFileEnumerator *enumerator;
GFileInfo *info;
GError *error;
-
+
if (file == NULL)
return;
-
- request = G_FILE_INFO_FILE_TYPE | G_FILE_INFO_NAME | G_FILE_INFO_SIZE | G_FILE_INFO_IS_HIDDEN;
+ if (attributes == NULL)
+ attributes = "*";
+
error = NULL;
- enumerator = g_file_enumerate_children (file, request, attributes, TRUE, NULL, &error);
+ enumerator = g_file_enumerate_children (file, attributes, 0, NULL, &error);
if (enumerator == NULL)
{
g_print ("Error: %s\n", error->message);