Add:binding_bus:Cleanup and Search functions
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Fri, 13 Nov 2009 14:33:22 +0000 (14:33 +0000)
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Fri, 13 Nov 2009 14:33:22 +0000 (14:33 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk/navit@2755 ffa7fe5e-494d-0410-b361-a75ebd5db220

navit/binding/dbus/binding_dbus.c
navit/map.c
navit/search.c

index dbfdfb7..1f31721 100644 (file)
@@ -38,6 +38,7 @@
 #include "vehicle.h"
 #include "map.h"
 #include "mapset.h"
+#include "search.h"
 #include "util.h"
 
 
@@ -68,7 +69,7 @@ object_new(char *type, void *object)
 {
        int id;
        char *ret;
-       dbg(0,"enter %s\n", type);
+       dbg(1,"enter %s\n", type);
        if ((ret=g_hash_table_lookup(object_hash_rev, object)))
                return ret;
        id=GPOINTER_TO_INT(g_hash_table_lookup(object_count, type));
@@ -76,7 +77,7 @@ object_new(char *type, void *object)
        ret=g_strdup_printf("%s/%s/%d", object_path, type, id);
        g_hash_table_insert(object_hash, ret, object);
        g_hash_table_insert(object_hash_rev, object, ret);
-       dbg(0,"return %s\n", ret);
+       dbg(1,"return %s\n", ret);
        return (ret);
 }
 
@@ -86,6 +87,19 @@ object_get(const char *path)
        return g_hash_table_lookup(object_hash, path);
 }
 
+static void 
+object_destroy(const char *path, void *object)
+{
+       if (!path && !object)
+               return;
+       if (!object)
+               object=g_hash_table_lookup(object_hash, path);
+       if (!path)
+               path=g_hash_table_lookup(object_hash_rev, object);
+       g_hash_table_remove(object_hash, path);
+       g_hash_table_remove(object_hash_rev, object);
+}
+
 static void *
 resolve_object(const char *opath, char *type)
 {
@@ -181,6 +195,25 @@ attr_type_get_from_message(DBusMessageIter *iter)
        return attr_from_name(attr_type); 
 }
 
+static void
+encode_variant_string(DBusMessageIter *iter, char *str)
+{
+       DBusMessageIter variant;
+       dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &variant);
+       dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING, &str);
+       dbus_message_iter_close_container(iter, &variant);
+}
+
+static void
+encode_dict_string_variant_string(DBusMessageIter *iter, char *key, char *value)
+{
+       DBusMessageIter dict;
+       dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
+       dbus_message_iter_append_basic(&dict, DBUS_TYPE_STRING, &key);
+       encode_variant_string(&dict, value);
+       dbus_message_iter_close_container(iter, &dict);
+}
+
 static int
 encode_attr(DBusMessage *message, struct attr *attr)
 {
@@ -199,9 +232,7 @@ encode_attr(DBusMessage *message, struct attr *attr)
                dbus_message_iter_close_container(&iter1, &iter2);
        }
        if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end) {
-               dbus_message_iter_open_container(&iter1, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &iter2);
-               dbus_message_iter_append_basic(&iter2, DBUS_TYPE_STRING, &attr->u.str);
-               dbus_message_iter_close_container(&iter1, &iter2);
+               encode_variant_string(&iter1, attr->u.str);
        }
        if (attr->type >= attr_type_object_begin && attr->type <= attr_type_object_end) {
                char *object=object_new(attr_to_name(attr->type), attr->u.data);
@@ -261,6 +292,69 @@ dbus_error_invalid_object_path_parameter(DBusConnection *connection, DBusMessage
        return dbus_error(connection, message, DBUS_ERROR_BAD_ADDRESS, "object path parameter invalid");
 }
 
+#if 0
+static void
+dbus_dump_iter(char *prefix, DBusMessageIter *iter)
+{
+       char *prefixr,*vals;
+       int arg,vali;
+       DBusMessageIter iterr;
+       while ((arg=dbus_message_iter_get_arg_type(iter)) != DBUS_TYPE_INVALID) {
+               switch (arg) {
+               case DBUS_TYPE_INT32:
+                       dbus_message_iter_get_basic(iter, &vali);
+                       dbg(0,"%sDBUS_TYPE_INT32: %d\n",prefix,vali);
+                       break;
+               case DBUS_TYPE_STRING:
+                       dbus_message_iter_get_basic(iter, &vals);
+                       dbg(0,"%sDBUS_TYPE_STRING: %s\n",prefix,vals);
+                       break;
+               case DBUS_TYPE_STRUCT:
+                       dbg(0,"%sDBUS_TYPE_STRUCT:\n",prefix);
+                       prefixr=g_strdup_printf("%s  ",prefix);
+                       dbus_message_iter_recurse(iter, &iterr);
+                       dbus_dump_iter(prefixr, &iterr);
+                       g_free(prefixr);
+                       break;
+               case DBUS_TYPE_VARIANT:
+                       dbg(0,"%sDBUS_TYPE_VARIANT:\n",prefix);
+                       prefixr=g_strdup_printf("%s  ",prefix);
+                       dbus_message_iter_recurse(iter, &iterr);
+                       dbus_dump_iter(prefixr, &iterr);
+                       g_free(prefixr);
+                       break;
+               case DBUS_TYPE_DICT_ENTRY:
+                       dbg(0,"%sDBUS_TYPE_DICT_ENTRY:\n",prefix);
+                       prefixr=g_strdup_printf("%s  ",prefix);
+                       dbus_message_iter_recurse(iter, &iterr);
+                       dbus_dump_iter(prefixr, &iterr);
+                       g_free(prefixr);
+                       break;
+               case DBUS_TYPE_ARRAY:
+                       dbg(0,"%sDBUS_TYPE_ARRAY:\n",prefix);
+                       prefixr=g_strdup_printf("%s  ",prefix);
+                       dbus_message_iter_recurse(iter, &iterr);
+                       dbus_dump_iter(prefixr, &iterr);
+                       g_free(prefixr);
+                       break;
+               default:
+                       dbg(0,"%c\n",arg);
+               }
+               dbus_message_iter_next(iter);
+       }
+}
+
+static void
+dbus_dump(DBusMessage *message)
+{
+       DBusMessageIter iter;
+
+       dbus_message_iter_init(message, &iter);
+       dbus_dump_iter("",&iter);
+               
+}
+#endif
+
 /**
  * Extracts a struct pcoord from a DBus message
  *
@@ -315,25 +409,53 @@ pcoord_get_from_message(DBusMessage *message, DBusMessageIter *iter, struct pcoo
     
 }
 
-static int
-decode_attr(DBusMessage *message, struct attr *attr)
+static void
+pcoord_encode(DBusMessageIter *iter, struct pcoord *pc)
+{
+       DBusMessageIter iter2;
+       dbus_message_iter_open_container(iter,DBUS_TYPE_STRUCT,NULL,&iter2);
+       if (pc) {
+               dbus_message_iter_append_basic(&iter2, DBUS_TYPE_INT32, &pc->pro);
+               dbus_message_iter_append_basic(&iter2, DBUS_TYPE_INT32, &pc->x);
+               dbus_message_iter_append_basic(&iter2, DBUS_TYPE_INT32, &pc->y);
+       } else {
+               int n=0;
+               dbus_message_iter_append_basic(&iter2, DBUS_TYPE_INT32, &n);
+               dbus_message_iter_append_basic(&iter2, DBUS_TYPE_INT32, &n);
+               dbus_message_iter_append_basic(&iter2, DBUS_TYPE_INT32, &n);
+       }
+       dbus_message_iter_close_container(iter, &iter2);
+}
+
+static enum attr_type
+decode_attr_type_from_iter(DBusMessageIter *iter)
 {
-       DBusMessageIter iter, iterattr, iterstruct;
        char *attr_type;
+       enum attr_type ret;
+       
+       if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
+               return attr_none;
+       dbus_message_iter_get_basic(iter, &attr_type);
+       dbus_message_iter_next(iter);
+       ret=attr_from_name(attr_type); 
+       dbg(1, "attr value: 0x%x string: %s\n", ret, attr_type);
+       return ret;
+}
+
+static int
+decode_attr_from_iter(DBusMessageIter *iter, struct attr *attr)
+{
+       DBusMessageIter iterattr, iterstruct;
        int ret=1;
        double d;
 
-       dbus_message_iter_init(message, &iter);
-       dbus_message_iter_get_basic(&iter, &attr_type);
-       attr->type = attr_from_name(attr_type); 
-       dbg(0, "attr value: 0x%x string: %s\n", attr->type, attr_type);
-    
+       attr->type=decode_attr_type_from_iter(iter);
        if (attr->type == attr_none)
                return 0;
     
-       dbus_message_iter_next(&iter);
-       dbus_message_iter_recurse(&iter, &iterattr);
-       dbg(0, "seems valid. signature: %s\n", dbus_message_iter_get_signature(&iterattr));
+       dbus_message_iter_recurse(iter, &iterattr);
+       dbus_message_iter_next(iter);
+       dbg(1, "seems valid. signature: %s\n", dbus_message_iter_get_signature(&iterattr));
     
        if (attr->type >= attr_type_item_begin && attr->type <= attr_type_item_end)
                return 0;
@@ -391,6 +513,15 @@ decode_attr(DBusMessage *message, struct attr *attr)
        return 0;
 }
 
+static int
+decode_attr(DBusMessage *message, struct attr *attr)
+{
+       DBusMessageIter iter;
+
+       dbus_message_iter_init(message, &iter);
+       return decode_attr_from_iter(&iter, attr);
+}
+
 static void
 destroy_attr(struct attr *attr)
 {
@@ -438,11 +569,25 @@ request_attr_iter_destroy(DBusConnection *connection, DBusMessage *message, char
        g_free(iter_name);
        if (! attr_iter)
                return dbus_error_invalid_object_path_parameter(connection, message);
+       object_destroy(NULL, attr_iter);
        func(attr_iter);
 
        return empty_reply(connection, message);
 }
 
+static DBusHandlerResult
+request_destroy(DBusConnection *connection, DBusMessage *message, char *type, void *data, void (*func)(void *))
+{
+       if (!data) 
+               data=object_get_from_message(message, type);
+       if (!data)
+               return dbus_error_invalid_object_path(connection, message);
+       object_destroy(NULL, data);
+       func(data);
+
+       return empty_reply(connection, message);
+}
+
 
 static DBusHandlerResult
 request_get_attr(DBusConnection *connection, DBusMessage *message, char *type, void *data, int (*func)(void *data, enum attr_type type, struct attr *attr, struct attr_iter *iter))
@@ -517,6 +662,8 @@ request_config_attr_iter_destroy(DBusConnection *connection, DBusMessage *messag
        return request_attr_iter_destroy(connection, message, "config", (void (*)(struct attr_iter *))config_attr_iter_destroy);
 }
 
+
+
 /* graphics */
 
 static DBusHandlerResult
@@ -972,7 +1119,146 @@ request_navit_evaluate(DBusConnection *connection, DBusMessage *message)
        return DBUS_HANDLER_RESULT_HANDLED;
 }
 
+/* search_list */
+
+static DBusHandlerResult
+request_search_list_destroy(DBusConnection *connection, DBusMessage *message)
+{
+       return request_destroy(connection, message, "search_list", NULL, (void (*)(void *)) search_list_destroy);
+}
+
+static DBusHandlerResult
+request_search_list_get_result(DBusConnection *connection, DBusMessage *message)
+{
+       struct search_list *search_list;
+       struct search_list_result *result;
+       DBusMessage *reply;
+       DBusMessageIter iter,iter2,iter3,iter4;
+       char *country="country";
+       char *town="town";
+       char *street="street";
+
+       search_list = object_get_from_message(message, "search_list");
+       if (! search_list)
+               return dbus_error_invalid_object_path(connection, message);
+       result=search_list_get_result(search_list);
+       if (!result)
+               return empty_reply(connection, message);
+       reply = dbus_message_new_method_return(message);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &result->id);
+       pcoord_encode(&iter, result->c);
+       dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sa{sv}}", &iter2);
+       if (result->country && (result->country->car || result->country->iso2 || result->country->iso3 || result->country->name)) {
+               dbus_message_iter_open_container(&iter2, DBUS_TYPE_DICT_ENTRY, NULL, &iter3);
+               dbus_message_iter_append_basic(&iter3, DBUS_TYPE_STRING, &country);
+               dbus_message_iter_open_container(&iter3, DBUS_TYPE_ARRAY, "{sv}", &iter4);
+               if (result->country->car) 
+                       encode_dict_string_variant_string(&iter4, "car", result->country->car);
+               if (result->country->iso2) 
+                       encode_dict_string_variant_string(&iter4, "iso2", result->country->iso2);
+               if (result->country->iso3) 
+                       encode_dict_string_variant_string(&iter4, "iso3", result->country->iso3);
+               if (result->country->name) 
+                       encode_dict_string_variant_string(&iter4, "name", result->country->name);
+               dbus_message_iter_close_container(&iter3, &iter4);
+               dbus_message_iter_close_container(&iter2, &iter3);
+       }
+       if (result->town && (result->town->district || result->town->name)) {
+               dbus_message_iter_open_container(&iter2, DBUS_TYPE_DICT_ENTRY, NULL, &iter3);
+               dbus_message_iter_append_basic(&iter3, DBUS_TYPE_STRING, &town);
+               dbus_message_iter_open_container(&iter3, DBUS_TYPE_ARRAY, "{sv}", &iter4);
+               if (result->town->district)
+                       encode_dict_string_variant_string(&iter4, "district", result->town->district);
+               if (result->town->name)
+                       encode_dict_string_variant_string(&iter4, "name", result->town->name);
+               dbus_message_iter_close_container(&iter3, &iter4);
+               dbus_message_iter_close_container(&iter2, &iter3);
+       }
+       if (result->street && result->street->name) {
+               dbus_message_iter_open_container(&iter2, DBUS_TYPE_DICT_ENTRY, NULL, &iter3);
+               dbus_message_iter_append_basic(&iter3, DBUS_TYPE_STRING, &street);
+               dbus_message_iter_open_container(&iter3, DBUS_TYPE_ARRAY, "{sv}", &iter4);
+               if (result->street->name)
+                       encode_dict_string_variant_string(&iter4, "name", result->street->name);
+               dbus_message_iter_close_container(&iter3, &iter4);
+               dbus_message_iter_close_container(&iter2, &iter3);
+       }
+       dbus_message_iter_close_container(&iter, &iter2);
+       dbus_connection_send (connection, reply, NULL);
+       dbus_message_unref (reply);
+       return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+request_search_list_new(DBusConnection *connection, DBusMessage *message)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       struct mapset *mapset;
+       struct search_list *search_list;
+       char *opath;
+
+       dbus_message_iter_init(message, &iter);
+       mapset=object_get_from_message_arg(&iter, "mapset");
+       if (! mapset)
+               return dbus_error_invalid_object_path_parameter(connection, message);
+       search_list=search_list_new(mapset);
+       opath=object_new("search_list", search_list);
+       reply = dbus_message_new_method_return(message);
+       dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID);
+       dbus_connection_send (connection, reply, NULL);
+       dbus_message_unref (reply);
+       return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+request_search_list_search(DBusConnection *connection, DBusMessage *message)
+{
+       DBusMessageIter iter;
+       struct search_list *search_list;
+       struct attr attr;
+       int partial;
+
+       search_list = object_get_from_message(message, "search_list");
+       if (! search_list)
+               return dbus_error_invalid_object_path(connection, message);
 
+       dbus_message_iter_init(message, &iter);
+       if (!decode_attr_from_iter(&iter, &attr))
+               return dbus_error_invalid_parameter(connection, message);
+       if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) 
+               return dbus_error_invalid_parameter(connection, message);
+       dbus_message_iter_get_basic(&iter, &partial);
+       search_list_search(search_list, &attr, partial);
+       return empty_reply(connection, message);
+}
+
+static DBusHandlerResult
+request_search_list_select(DBusConnection *connection, DBusMessage *message)
+{
+       DBusMessageIter iter;
+       struct search_list *search_list;
+       int id, mode;
+       enum attr_type attr_type;
+
+       search_list = object_get_from_message(message, "search_list");
+       if (! search_list)
+               return dbus_error_invalid_object_path(connection, message);
+
+       dbus_message_iter_init(message, &iter);
+       attr_type=decode_attr_type_from_iter(&iter);    
+       if (attr_type == attr_none)
+               return dbus_error_invalid_parameter(connection, message);
+       if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) 
+               return dbus_error_invalid_parameter(connection, message);
+       dbus_message_iter_get_basic(&iter, &id);
+       if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) 
+               return dbus_error_invalid_parameter(connection, message);
+       dbus_message_iter_get_basic(&iter, &mode);
+       search_list_select(search_list, attr_type, id, mode);
+       return empty_reply(connection, message);
+}
 
 /* vehicle */
 
@@ -1009,6 +1295,7 @@ struct dbus_method {
        {"",        "attr_iter_destroy",   "o",       "attr_iter",                               "",   "",      request_config_attr_iter_destroy},
        {"",        "get_attr",            "s",       "attrname",                                "sv", "attrname,value",request_config_get_attr},
        {"",        "get_attr_wi",         "so",      "attrname,attr_iter",                      "sv", "attrname,value",request_config_get_attr},
+       {"",        "search_list_new",     "o",       "mapset",                                  "o",  "search",request_search_list_new},
        {".graphics","get_data",           "s",       "type",                                    "ay",  "data", request_graphics_get_data},
        {".graphics","set_attr",           "sv",      "attribute,value",                         "",   "",      request_graphics_set_attr},
        {".navit",  "draw",                "",        "",                                        "",   "",      request_navit_draw},
@@ -1039,6 +1326,10 @@ struct dbus_method {
        {".mapset", "attr_iter_destroy",   "o",       "attr_iter",                               "",   "",      request_mapset_attr_iter_destroy},
        {".mapset", "get_attr",            "s",       "attribute",                               "sv",  "attrname,value", request_mapset_get_attr},
        {".mapset", "get_attr_wi",         "so",      "attribute,attr_iter",                     "sv",  "attrname,value", request_mapset_get_attr},
+       {".search_list","destroy",         "",        "",                                        "",   "",      request_search_list_destroy},
+       {".search_list","get_result",      "",        "",                                        "i(iii)a{sa{sv}}",   "id,coord,dict",      request_search_list_get_result},
+       {".search_list","search",          "svi",     "attribute,value,partial",                 "",   "",      request_search_list_search},
+       {".search_list","select",          "sii",     "attribute_type,id,mode",                  "",   "",      request_search_list_select},
        {".vehicle","set_attr",            "sv",      "attribute,value",                         "",   "",      request_vehicle_set_attr},
 };
 
@@ -1052,7 +1343,7 @@ introspect_path(const char *object)
        if (strncmp(object, object_path, strlen(object_path)))
                return NULL;
        ret=g_strdup(object+strlen(object_path));
-       dbg(0,"path=%s\n",ret);
+       dbg(1,"path=%s\n",ret);
        for (i = strlen(ret)-1 ; i >= 0 ; i--) {
                if (ret[i] == '/' || (ret[i] >= '0' && ret[i] <= '9'))
                        ret[i]='\0';
@@ -1080,7 +1371,7 @@ generate_navitintrospectxml(const char *object)
     char *path=introspect_path(object);
     if (!path)
        return NULL;
-    dbg(0,"path=%s\n",path);
+    dbg(1,"path=%s\n",path);
     
     // write header and make navit introspectable
     navitintrospectxml = g_strdup_printf("%s%s%s\n", navitintrospectxml_head1, object, navitintrospectxml_head2);
@@ -1127,7 +1418,7 @@ navit_handler_func(DBusConnection *connection, DBusMessage *message, void *user_
        if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
                DBusMessage *reply;
                char *navitintrospectxml = generate_navitintrospectxml(dbus_message_get_path(message));
-               dbg(0,"Introspect %s:Result:%s\n",dbus_message_get_path(message), navitintrospectxml);
+               dbg(1,"Introspect %s:Result:%s\n",dbus_message_get_path(message), navitintrospectxml);
                if (navitintrospectxml) {
                        reply = dbus_message_new_method_return(message);
                        dbus_message_append_args(reply, DBUS_TYPE_STRING, &navitintrospectxml, DBUS_TYPE_INVALID);
index c14d2b4..8a6408b 100644 (file)
@@ -393,7 +393,7 @@ map_search_new(struct map *m, struct item *item, struct attr *search_attr, int p
        this_=g_new0(struct map_search,1);
        this_->m=m;
        this_->search_attr=*search_attr;
-       if (search_attr->type >= attr_country_all && search_attr->type <= attr_country_name)
+       if ((search_attr->type >= attr_country_all && search_attr->type <= attr_country_name) || search_attr->type == attr_country_id)
                this_->priv=country_search_new(&this_->search_attr, partial);
        else {
                if (m->meth.map_search_new) {
@@ -429,7 +429,7 @@ map_search_get_item(struct map_search *this_)
 
        if (! this_)
                return NULL;
-       if (this_->search_attr.type >= attr_country_all && this_->search_attr.type <= attr_country_name)
+       if ((this_->search_attr.type >= attr_country_all && this_->search_attr.type <= attr_country_name) || this_->search_attr.type == attr_country_id)
                return country_search_get_item(this_->priv);
        ret=this_->m->meth.map_search_get_item(this_->priv);
        if (ret)
index a7d0007..74cb848 100644 (file)
@@ -30,7 +30,7 @@
 struct search_list_level {
        struct mapset *ms;
        struct search_list_common *parent;
-       struct attr attr;
+       struct attr *attr;
        int partial;
        int selected;
        struct mapset_search *search;
@@ -115,10 +115,8 @@ search_list_search(struct search_list *this_, struct attr *search_attr, int part
                this_->result.id=0;
                this_->level=level;
                le=&this_->levels[level];
-               le->attr=*search_attr;
-               if (search_attr->type != attr_country_id)
-                       le->attr.u.str=g_strdup(search_attr->u.str);
                search_list_search_free(this_, level);
+               le->attr=attr_dup(search_attr);
                le->partial=partial;
                if (level > 0) {
                        le=&this_->levels[level-1];
@@ -360,6 +358,7 @@ search_list_search_free(struct search_list *sl, int level)
                next=g_list_next(curr);
                curr=next;
        }
+       attr_free(le->attr);
        g_list_free(le->list);
        le->list=NULL;
        le->curr=NULL;
@@ -450,8 +449,8 @@ search_list_get_result(struct search_list *this_)
                        }
                        if (le->parent)
                                dbg(1,"mapset_search_new with item(%d,%d)\n", le->parent->item.id_hi, le->parent->item.id_lo);
-                       dbg(1,"attr=%s\n", attr_to_name(le->attr.type));
-                       le->search=mapset_search_new(this_->ms, &le->parent->item, &le->attr, le->partial);
+                       dbg(1,"attr=%s\n", attr_to_name(le->attr->type));
+                       le->search=mapset_search_new(this_->ms, &le->parent->item, le->attr, le->partial);
                        le->hash=g_hash_table_new(search_item_hash_hash, search_item_hash_equal);
                }
                dbg(1,"le->search=%p\n", le->search);