diff options
author | Alexander Larsson <alexl@redhat.com> | 2009-02-27 12:59:47 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2009-02-27 12:59:47 +0000 |
commit | 28713ed6b20cb617bce93e639b764617a118e1dd (patch) | |
tree | 8e840db7df291d1c60a55eb0aba9364ae89bde73 /common | |
parent | 4c1cbdac8d59b1bf53319bc9e5a165c8b11adacb (diff) | |
download | gvfs-28713ed6b20cb617bce93e639b764617a118e1dd.tar.gz |
Add (de)marshalling functions for GFileInfos.
2009-02-27 Alexander Larsson <alexl@redhat.com>
* common/Makefile.am:
* common/gvfsfileinfo.[ch]:
Add (de)marshalling functions for GFileInfos.
* common/gvfsdaemonprotocol.h:
Add protocol extensions for query info over streams
* client/gdaemonfileinputstream.c:
Support sync query_info.
* daemon/Makefile.am:
* daemon/gvfsjobqueryinforead.[ch]:
* daemon/gvfsbackend.h:
Added query info job and backend call for input streams
* daemon/gvfsbackendtest.c:
Implement query_info_on_read
* daemon/gvfschannel.[ch]:
Add g_vfs_channel_send_info
* daemon/gvfsreadchannel.c:
(read_channel_handle_request):
Handle query info
* test/Makefile.am:
* test/test-query-info-stream.c:
Add test for stream query info.
svn path=/trunk/; revision=2257
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile.am | 1 | ||||
-rw-r--r-- | common/gvfsdaemonprotocol.h | 6 | ||||
-rw-r--r-- | common/gvfsfileinfo.c | 278 | ||||
-rw-r--r-- | common/gvfsfileinfo.h | 37 |
4 files changed, 322 insertions, 0 deletions
diff --git a/common/Makefile.am b/common/Makefile.am index 56cc74e1..380dc654 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -17,6 +17,7 @@ libgvfscommon_la_SOURCES = \ gmounttracker.c gmounttracker.h \ gvfsdaemonprotocol.c gvfsdaemonprotocol.h \ gvfsicon.h gvfsicon.c \ + gvfsfileinfo.c gvfsfileinfo.h \ $(NULL) libgvfscommon_la_LIBADD = \ diff --git a/common/gvfsdaemonprotocol.h b/common/gvfsdaemonprotocol.h index 38f7d0d3..dedf86ba 100644 --- a/common/gvfsdaemonprotocol.h +++ b/common/gvfsdaemonprotocol.h @@ -113,6 +113,7 @@ typedef struct { #define G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_CANCEL 3 #define G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SEEK_SET 4 #define G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_SEEK_END 5 +#define G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_QUERY_INFO 6 /* read, readahead reply: @@ -123,6 +124,10 @@ type, pos (64), error: type, code, size, data (size bytes, 2 strings: domain, message) + +info: +type, 0, size, data + */ typedef struct { @@ -139,6 +144,7 @@ typedef struct { #define G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SEEK_POS 2 #define G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_WRITTEN 3 #define G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_CLOSED 4 +#define G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_INFO 5 #define G_FILE_INFO_INNER_TYPE_AS_STRING \ DBUS_TYPE_ARRAY_AS_STRING \ diff --git a/common/gvfsfileinfo.c b/common/gvfsfileinfo.c new file mode 100644 index 00000000..df563cc7 --- /dev/null +++ b/common/gvfsfileinfo.c @@ -0,0 +1,278 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alexander Larsson <alexl@redhat.com> + */ + +#include <config.h> + +#include <gio/gio.h> +#include <string.h> +#include "gvfsfileinfo.h" + +static void +put_string (GDataOutputStream *out, + const char *str) +{ + gsize len; + + len = strlen (str); + if (len > G_MAXUINT16) + { + g_warning ("GFileInfo string to large, (%d bytes)\n", (int)len); + len = 0; + str = ""; + } + + g_data_output_stream_put_uint16 (out, len, + NULL, NULL); + g_data_output_stream_put_string (out, str, NULL, NULL); +} + +static char * +read_string (GDataInputStream *in) +{ + gsize len; + char *str; + + len = g_data_input_stream_read_uint16 (in, NULL, NULL); + str = g_malloc (len + 1); + g_input_stream_read_all (G_INPUT_STREAM (in), str, len, &len, NULL, NULL); + str[len] = 0; + return str; +} + +char * +gvfs_file_info_marshal (GFileInfo *info, + gsize *size) +{ + GOutputStream *memstream; + GDataOutputStream *out; + GFileAttributeType type; + GFileAttributeStatus status; + GObject *obj; + char **attrs, *attr; + char *data; + int i; + + memstream = g_memory_output_stream_new (NULL, 0, g_realloc, NULL); + + out = g_data_output_stream_new (memstream); + g_object_unref (memstream); + + attrs = g_file_info_list_attributes (info, NULL); + + g_data_output_stream_put_uint32 (out, + g_strv_length (attrs), + NULL, NULL); + + for (i = 0; attrs[i] != NULL; i++) + { + attr = attrs[i]; + + type = g_file_info_get_attribute_type (info, attr); + status = g_file_info_get_attribute_status (info, attr); + + put_string (out, attr); + g_data_output_stream_put_byte (out, type, + NULL, NULL); + g_data_output_stream_put_byte (out, status, + NULL, NULL); + + switch (type) + { + case G_FILE_ATTRIBUTE_TYPE_STRING: + put_string (out, g_file_info_get_attribute_string (info, attr)); + break; + case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: + put_string (out, g_file_info_get_attribute_byte_string (info, attr)); + break; + case G_FILE_ATTRIBUTE_TYPE_BOOLEAN: + g_data_output_stream_put_byte (out, + g_file_info_get_attribute_boolean (info, attr), + NULL, NULL); + break; + case G_FILE_ATTRIBUTE_TYPE_UINT32: + g_data_output_stream_put_uint32 (out, + g_file_info_get_attribute_uint32 (info, attr), + NULL, NULL); + break; + case G_FILE_ATTRIBUTE_TYPE_INT32: + g_data_output_stream_put_int32 (out, + g_file_info_get_attribute_int32 (info, attr), + NULL, NULL); + break; + case G_FILE_ATTRIBUTE_TYPE_UINT64: + g_data_output_stream_put_uint64 (out, + g_file_info_get_attribute_uint64 (info, attr), + NULL, NULL); + break; + case G_FILE_ATTRIBUTE_TYPE_INT64: + g_data_output_stream_put_int64 (out, + g_file_info_get_attribute_int64 (info, attr), + NULL, NULL); + break; + case G_FILE_ATTRIBUTE_TYPE_OBJECT: + obj = g_file_info_get_attribute_object (info, attr); + if (obj == NULL) + { + g_data_output_stream_put_byte (out, 0, + NULL, NULL); + } + else if (G_IS_ICON (obj)) + { + char *icon_str; + + icon_str = g_icon_to_string (G_ICON (obj)); + g_data_output_stream_put_byte (out, 1, + NULL, NULL); + put_string (out, icon_str); + g_free (icon_str); + } + else + { + g_warning ("Unsupported GFileInfo object type %s\n", + g_type_name_from_instance ((GTypeInstance *)obj)); + g_data_output_stream_put_byte (out, 0, + NULL, NULL); + } + break; + case G_FILE_ATTRIBUTE_TYPE_INVALID: + default: + break; + } + } + + data = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (memstream)); + *size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (memstream)); + g_object_unref (out); + g_strfreev (attrs); + return data; +} + +GFileInfo * +gvfs_file_info_demarshal (char *data, + gsize size) +{ + guint32 num_attrs, i; + GInputStream *memstream; + GDataInputStream *in; + GFileInfo *info; + char *attr, *str; + GFileAttributeType type; + GFileAttributeStatus status; + GObject *obj; + int objtype; + + memstream = g_memory_input_stream_new_from_data (data, size, NULL); + in = g_data_input_stream_new (memstream); + g_object_unref (memstream); + + info = g_file_info_new (); + num_attrs = g_data_input_stream_read_uint32 (in, NULL, NULL); + + for (i = 0; i < num_attrs; i++) + { + attr = read_string (in); + type = g_data_input_stream_read_byte (in, NULL, NULL); + status = g_data_input_stream_read_byte (in, NULL, NULL); + + /* TODO: There is no way to set the status. This is required for + g_file_set_attributes_from_info() */ + + switch (type) + { + case G_FILE_ATTRIBUTE_TYPE_STRING: + str = read_string (in); + g_file_info_set_attribute_string (info, attr, str); + g_free (str); + break; + case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: + str = read_string (in); + g_file_info_set_attribute_byte_string (info, attr, str); + g_free (str); + break; + case G_FILE_ATTRIBUTE_TYPE_BOOLEAN: + g_file_info_set_attribute_boolean (info, attr, + g_data_input_stream_read_byte (in, + NULL, + NULL)); + break; + case G_FILE_ATTRIBUTE_TYPE_UINT32: + g_file_info_set_attribute_uint32 (info, attr, + g_data_input_stream_read_uint32 (in, + NULL, + NULL)); + break; + case G_FILE_ATTRIBUTE_TYPE_INT32: + g_file_info_set_attribute_int32 (info, attr, + g_data_input_stream_read_int32 (in, + NULL, + NULL)); + break; + case G_FILE_ATTRIBUTE_TYPE_UINT64: + g_file_info_set_attribute_uint64 (info, attr, + g_data_input_stream_read_uint64 (in, + NULL, + NULL)); + break; + case G_FILE_ATTRIBUTE_TYPE_INT64: + g_file_info_set_attribute_int64 (info, attr, + g_data_input_stream_read_int64 (in, + NULL, + NULL)); + break; + case G_FILE_ATTRIBUTE_TYPE_OBJECT: + objtype = g_data_input_stream_read_byte (in, NULL, NULL); + obj = NULL; + + if (objtype == 1) + { + char *icon_str; + + icon_str = read_string (in); + obj = (GObject *)g_icon_new_for_string (icon_str, NULL); + g_free (icon_str); + } + else + { + g_warning ("Unsupported GFileInfo object type %d\n", objtype); + g_free (attr); + goto out; + } + g_file_info_set_attribute_object (info, attr, obj); + if (obj) + g_object_unref (obj); + break; + case G_FILE_ATTRIBUTE_TYPE_INVALID: + default: + g_warning ("Unsupported GFileInfo attribute type %d\n", type); + g_free (attr); + goto out; + break; + } + g_free (attr); + } + + out: + g_object_unref (in); + return info; +} + + diff --git a/common/gvfsfileinfo.h b/common/gvfsfileinfo.h new file mode 100644 index 00000000..970f9e4f --- /dev/null +++ b/common/gvfsfileinfo.h @@ -0,0 +1,37 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alexander Larsson <alexl@redhat.com> + */ + +#ifndef __G_VFS_FILE_INFO_H__ +#define __G_VFS_FILE_INFO_H__ + +#include <glib.h> + +G_BEGIN_DECLS + +char * gvfs_file_info_marshal (GFileInfo *info, + gsize *size); +GFileInfo *gvfs_file_info_demarshal (char *data, + gsize size); + +G_END_DECLS + +#endif /* __G_VFS_FILE_INFO_H__ */ |