qom: add object_resolve_path_type
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 3 Feb 2012 10:21:01 +0000 (11:21 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 7 Feb 2012 12:52:41 +0000 (13:52 +0100)
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
include/qemu/object.h
qom/object.c

index b27f80e0bd98b440aa111641ac2564072ee39cdc..6c36345814b9b88f7bcd752201b1d4f29df0140d 100644 (file)
@@ -749,13 +749,34 @@ gchar *object_get_canonical_path(Object *obj);
  * specifying objects easy.  At each level of the composition tree, the partial
  * path is matched as an absolute path.  The first match is not returned.  At
  * least two matches are searched for.  A successful result is only returned if
- * only one match is founded.  If more than one match is found, a flag is
- * return to indicate that the match was ambiguous.
+ * only one match is found.  If more than one match is found, a flag is
+ * returned to indicate that the match was ambiguous.
  *
  * Returns: The matched object or NULL on path lookup failure.
  */
 Object *object_resolve_path(const char *path, bool *ambiguous);
 
+/**
+ * object_resolve_path_type:
+ * @path: the path to resolve
+ * @typename: the type to look for.
+ * @ambiguous: returns true if the path resolution failed because of an
+ *   ambiguous match
+ *
+ * This is similar to object_resolve_path.  However, when looking for a
+ * partial path only matches that implement the given type are considered.
+ * This restricts the search and avoids spuriously flagging matches as
+ * ambiguous.
+ *
+ * For both partial and absolute paths, the return value goes through
+ * a dynamic cast to @typename.  This is important if either the link,
+ * or the typename itself are of interface types.
+ *
+ * Returns: The matched object or NULL on path lookup failure.
+ */
+Object *object_resolve_path_type(const char *path, const char *typename,
+                                 bool *ambiguous);
+
 /**
  * object_property_add_child:
  * @obj: the object to add a property to
index 7fd37cb879a0051e346590ba7b92baf3dc0606a0..ea0efc662ac5d92d6bfbe185c29e79c67ef23dc3 100644 (file)
@@ -930,17 +930,18 @@ gchar *object_get_canonical_path(Object *obj)
 
 static Object *object_resolve_abs_path(Object *parent,
                                           gchar **parts,
+                                          const char *typename,
                                           int index)
 {
     ObjectProperty *prop;
     Object *child;
 
     if (parts[index] == NULL) {
-        return parent;
+        return object_dynamic_cast(parent, typename);
     }
 
     if (strcmp(parts[index], "") == 0) {
-        return object_resolve_abs_path(parent, parts, index + 1);
+        return object_resolve_abs_path(parent, parts, typename, index + 1);
     }
 
     prop = object_property_find(parent, parts[index]);
@@ -962,17 +963,18 @@ static Object *object_resolve_abs_path(Object *parent,
         return NULL;
     }
 
-    return object_resolve_abs_path(child, parts, index + 1);
+    return object_resolve_abs_path(child, parts, typename, index + 1);
 }
 
 static Object *object_resolve_partial_path(Object *parent,
                                               gchar **parts,
+                                              const char *typename,
                                               bool *ambiguous)
 {
     Object *obj;
     ObjectProperty *prop;
 
-    obj = object_resolve_abs_path(parent, parts, 0);
+    obj = object_resolve_abs_path(parent, parts, typename, 0);
 
     QTAILQ_FOREACH(prop, &parent->properties, node) {
         Object *found;
@@ -981,7 +983,8 @@ static Object *object_resolve_partial_path(Object *parent,
             continue;
         }
 
-        found = object_resolve_partial_path(prop->opaque, parts, ambiguous);
+        found = object_resolve_partial_path(prop->opaque, parts,
+                                            typename, ambiguous);
         if (found) {
             if (obj) {
                 if (ambiguous) {
@@ -1000,7 +1003,8 @@ static Object *object_resolve_partial_path(Object *parent,
     return obj;
 }
 
-Object *object_resolve_path(const char *path, bool *ambiguous)
+Object *object_resolve_path_type(const char *path, const char *typename,
+                                 bool *ambiguous)
 {
     bool partial_path = true;
     Object *obj;
@@ -1020,9 +1024,10 @@ Object *object_resolve_path(const char *path, bool *ambiguous)
         if (ambiguous) {
             *ambiguous = false;
         }
-        obj = object_resolve_partial_path(object_get_root(), parts, ambiguous);
+        obj = object_resolve_partial_path(object_get_root(), parts,
+                                          typename, ambiguous);
     } else {
-        obj = object_resolve_abs_path(object_get_root(), parts, 1);
+        obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
     }
 
     g_strfreev(parts);
@@ -1030,6 +1035,11 @@ Object *object_resolve_path(const char *path, bool *ambiguous)
     return obj;
 }
 
+Object *object_resolve_path(const char *path, bool *ambiguous)
+{
+    return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
+}
+
 typedef struct StringProperty
 {
     char *(*get)(Object *, Error **);