From bff8882e6c4cb07def45148fb2a364d85a593994 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 30 Oct 2008 18:19:06 -0300 Subject: [PATCH] obexd: Return an array of dictionary for ListFolder --- obexd/client/session.c | 127 ++++++++++++++++++++++++++++++++++++++--- obexd/client/session.h | 1 + 2 files changed, 119 insertions(+), 9 deletions(-) diff --git a/obexd/client/session.c b/obexd/client/session.c index 96e9be69f..87705fc9e 100644 --- a/obexd/client/session.c +++ b/obexd/client/session.c @@ -650,25 +650,128 @@ static GDBusMethodTable session_methods[] = { { } }; +static void append_variant(DBusMessageIter *iter, int type, void *val) +{ + DBusMessageIter value; + char sig[2] = { type, '\0' }; + + dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value); + + dbus_message_iter_append_basic(&value, type, val); + + dbus_message_iter_close_container(iter, &value); +} + +static void dict_append_entry(DBusMessageIter *dict, + const char *key, int type, void *val) +{ + DBusMessageIter entry; + + if (type == DBUS_TYPE_STRING) { + const char *str = *((const char **) val); + if (str == NULL) + return; + } + + dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, + NULL, &entry); + + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key); + + append_variant(&entry, type, val); + + dbus_message_iter_close_container(dict, &entry); +} + +static void xml_element(GMarkupParseContext *ctxt, + const gchar *element, + const gchar **names, + const gchar **values, + gpointer user_data, + GError **gerr) +{ + DBusMessageIter dict, *iter = user_data; + gchar *key; + gint i, dtype = DBUS_TYPE_STRING; + + if (strcasecmp("folder", element) != 0 && strcasecmp("file", element) != 0) + return; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); + + dict_append_entry(&dict, "Type", DBUS_TYPE_STRING, &element); + + /* FIXME: User, Group, Other permission must be reviewed */ + + i = 0; + for (key = (gchar *) names[i]; key; key = (gchar *) names[++i]) { + key[0] = g_ascii_toupper(key[0]); + if (strcmp("Accessed", key) == 0 || + strcmp("Created", key) == 0 || + strcmp("Modified", key)== 0 || + strcmp("Size", key)== 0) + dtype = DBUS_TYPE_UINT64; + + dict_append_entry(&dict, key, dtype, &values[i]); + } + + dbus_message_iter_close_container(iter, &dict); +} + +static const GMarkupParser parser = { + xml_element, + NULL, + NULL, + NULL, + NULL +}; + static void list_folder_callback(struct session_data *session, void *user_data) { - DBusMessage *message = user_data; + GMarkupParseContext *ctxt; + DBusMessage *reply; + DBusMessageIter iter; - g_dbus_send_reply(session->conn, message, DBUS_TYPE_INVALID); - dbus_message_unref(message); + reply = dbus_message_new_method_return(session->msg); + + if (session->filled == 0) + goto done; + + dbus_message_iter_init_append(reply, &iter); + + ctxt = g_markup_parse_context_new(&parser, 0, &iter, NULL); + g_markup_parse_context_parse(ctxt, session->buffer, + session->filled, NULL); + g_markup_parse_context_free(ctxt); + + session->filled = 0; + +done: + g_dbus_send_message(session->conn, reply); + dbus_message_unref(session->msg); + session->msg = NULL; } static void get_xfer_progress(GwObexXfer *xfer, gpointer user_data) { struct callback_data *callback = user_data; - char buf[1024]; - gint len; - - if (gw_obex_xfer_read(xfer, buf, sizeof(buf), &len, NULL) == FALSE) + struct session_data *session = callback->session; + gint bsize, bread; + gboolean ret; + + /* FIXME: Check buffer overflow */ + bsize = sizeof(session->buffer) - session->filled; + ret = gw_obex_xfer_read(xfer, session->buffer + session->filled, + bsize, &bread, NULL); + session->filled += bread; + if (ret == FALSE) goto complete; - if (len == gw_obex_xfer_object_size(xfer)) + if (bread == gw_obex_xfer_object_size(xfer)) goto complete; gw_obex_xfer_flush(xfer, NULL); @@ -723,6 +826,11 @@ static DBusMessage *list_folder(DBusConnection *connection, GwObexXfer *xfer; int err; + if (session->msg) + return g_dbus_create_error(message, + "org.openobex.Error.InProgress", + "Transfer in progress"); + if (session->obex == NULL) return g_dbus_create_error(message, "org.openobex.Error.Failed", @@ -745,9 +853,10 @@ static DBusMessage *list_folder(DBusConnection *connection, return NULL; } + session->msg = dbus_message_ref(message); + session->filled = 0; callback->session = session; callback->func = list_folder_callback; - callback->data = dbus_message_ref(message); gw_obex_xfer_set_callback(xfer, get_xfer_progress, callback); diff --git a/obexd/client/session.h b/obexd/client/session.h index 06e0c774b..86fb24def 100644 --- a/obexd/client/session.h +++ b/obexd/client/session.h @@ -40,6 +40,7 @@ struct session_data { int sock; int fd; DBusConnection *conn; + DBusMessage *msg; GwObex *obex; GwObexXfer *xfer; char buffer[4096]; -- 2.47.3