qemu/qom/object.c
<<
>>
Prefs
   1/*
   2 * QEMU Object Model
   3 *
   4 * Copyright IBM, Corp. 2011
   5 *
   6 * Authors:
   7 *  Anthony Liguori   <aliguori@us.ibm.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  10 * See the COPYING file in the top-level directory.
  11 */
  12
  13#include "qom/object.h"
  14#include "qemu-common.h"
  15#include "qapi/visitor.h"
  16#include "qapi/string-input-visitor.h"
  17#include "qapi/string-output-visitor.h"
  18#include "qapi/qmp/qerror.h"
  19#include "trace.h"
  20
  21/* TODO: replace QObject with a simpler visitor to avoid a dependency
  22 * of the QOM core on QObject?  */
  23#include "qom/qom-qobject.h"
  24#include "qapi/qmp/qobject.h"
  25#include "qapi/qmp/qbool.h"
  26#include "qapi/qmp/qint.h"
  27#include "qapi/qmp/qstring.h"
  28
  29#define MAX_INTERFACES 32
  30
  31typedef struct InterfaceImpl InterfaceImpl;
  32typedef struct TypeImpl TypeImpl;
  33
  34struct InterfaceImpl
  35{
  36    const char *typename;
  37};
  38
  39struct TypeImpl
  40{
  41    const char *name;
  42
  43    size_t class_size;
  44
  45    size_t instance_size;
  46
  47    void (*class_init)(ObjectClass *klass, void *data);
  48    void (*class_base_init)(ObjectClass *klass, void *data);
  49    void (*class_finalize)(ObjectClass *klass, void *data);
  50
  51    void *class_data;
  52
  53    void (*instance_init)(Object *obj);
  54    void (*instance_finalize)(Object *obj);
  55
  56    bool abstract;
  57
  58    const char *parent;
  59    TypeImpl *parent_type;
  60
  61    ObjectClass *class;
  62
  63    int num_interfaces;
  64    InterfaceImpl interfaces[MAX_INTERFACES];
  65};
  66
  67static Type type_interface;
  68
  69static GHashTable *type_table_get(void)
  70{
  71    static GHashTable *type_table;
  72
  73    if (type_table == NULL) {
  74        type_table = g_hash_table_new(g_str_hash, g_str_equal);
  75    }
  76
  77    return type_table;
  78}
  79
  80static void type_table_add(TypeImpl *ti)
  81{
  82    g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
  83}
  84
  85static TypeImpl *type_table_lookup(const char *name)
  86{
  87    return g_hash_table_lookup(type_table_get(), name);
  88}
  89
  90static TypeImpl *type_register_internal(const TypeInfo *info)
  91{
  92    TypeImpl *ti = g_malloc0(sizeof(*ti));
  93    int i;
  94
  95    g_assert(info->name != NULL);
  96
  97    if (type_table_lookup(info->name) != NULL) {
  98        fprintf(stderr, "Registering `%s' which already exists\n", info->name);
  99        abort();
 100    }
 101
 102    ti->name = g_strdup(info->name);
 103    ti->parent = g_strdup(info->parent);
 104
 105    ti->class_size = info->class_size;
 106    ti->instance_size = info->instance_size;
 107
 108    ti->class_init = info->class_init;
 109    ti->class_base_init = info->class_base_init;
 110    ti->class_finalize = info->class_finalize;
 111    ti->class_data = info->class_data;
 112
 113    ti->instance_init = info->instance_init;
 114    ti->instance_finalize = info->instance_finalize;
 115
 116    ti->abstract = info->abstract;
 117
 118    for (i = 0; info->interfaces && info->interfaces[i].type; i++) {
 119        ti->interfaces[i].typename = g_strdup(info->interfaces[i].type);
 120    }
 121    ti->num_interfaces = i;
 122
 123    type_table_add(ti);
 124
 125    return ti;
 126}
 127
 128TypeImpl *type_register(const TypeInfo *info)
 129{
 130    assert(info->parent);
 131    return type_register_internal(info);
 132}
 133
 134TypeImpl *type_register_static(const TypeInfo *info)
 135{
 136    return type_register(info);
 137}
 138
 139static TypeImpl *type_get_by_name(const char *name)
 140{
 141    if (name == NULL) {
 142        return NULL;
 143    }
 144
 145    return type_table_lookup(name);
 146}
 147
 148static TypeImpl *type_get_parent(TypeImpl *type)
 149{
 150    if (!type->parent_type && type->parent) {
 151        type->parent_type = type_get_by_name(type->parent);
 152        g_assert(type->parent_type != NULL);
 153    }
 154
 155    return type->parent_type;
 156}
 157
 158static bool type_has_parent(TypeImpl *type)
 159{
 160    return (type->parent != NULL);
 161}
 162
 163static size_t type_class_get_size(TypeImpl *ti)
 164{
 165    if (ti->class_size) {
 166        return ti->class_size;
 167    }
 168
 169    if (type_has_parent(ti)) {
 170        return type_class_get_size(type_get_parent(ti));
 171    }
 172
 173    return sizeof(ObjectClass);
 174}
 175
 176static size_t type_object_get_size(TypeImpl *ti)
 177{
 178    if (ti->instance_size) {
 179        return ti->instance_size;
 180    }
 181
 182    if (type_has_parent(ti)) {
 183        return type_object_get_size(type_get_parent(ti));
 184    }
 185
 186    return 0;
 187}
 188
 189static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
 190{
 191    assert(target_type);
 192
 193    /* Check if typename is a direct ancestor of type */
 194    while (type) {
 195        if (type == target_type) {
 196            return true;
 197        }
 198
 199        type = type_get_parent(type);
 200    }
 201
 202    return false;
 203}
 204
 205static void type_initialize(TypeImpl *ti);
 206
 207static void type_initialize_interface(TypeImpl *ti, const char *parent)
 208{
 209    InterfaceClass *new_iface;
 210    TypeInfo info = { };
 211    TypeImpl *iface_impl;
 212
 213    info.parent = parent;
 214    info.name = g_strdup_printf("%s::%s", ti->name, info.parent);
 215    info.abstract = true;
 216
 217    iface_impl = type_register(&info);
 218    type_initialize(iface_impl);
 219    g_free((char *)info.name);
 220
 221    new_iface = (InterfaceClass *)iface_impl->class;
 222    new_iface->concrete_class = ti->class;
 223
 224    ti->class->interfaces = g_slist_append(ti->class->interfaces,
 225                                           iface_impl->class);
 226}
 227
 228static void type_initialize(TypeImpl *ti)
 229{
 230    TypeImpl *parent;
 231
 232    if (ti->class) {
 233        return;
 234    }
 235
 236    ti->class_size = type_class_get_size(ti);
 237    ti->instance_size = type_object_get_size(ti);
 238
 239    ti->class = g_malloc0(ti->class_size);
 240
 241    parent = type_get_parent(ti);
 242    if (parent) {
 243        type_initialize(parent);
 244        GSList *e;
 245        int i;
 246
 247        g_assert(parent->class_size <= ti->class_size);
 248        memcpy(ti->class, parent->class, parent->class_size);
 249        ti->class->interfaces = NULL;
 250
 251        for (e = parent->class->interfaces; e; e = e->next) {
 252            ObjectClass *iface = e->data;
 253            type_initialize_interface(ti, object_class_get_name(iface));
 254        }
 255
 256        for (i = 0; i < ti->num_interfaces; i++) {
 257            TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
 258            for (e = ti->class->interfaces; e; e = e->next) {
 259                TypeImpl *target_type = OBJECT_CLASS(e->data)->type;
 260
 261                if (type_is_ancestor(target_type, t)) {
 262                    break;
 263                }
 264            }
 265
 266            if (e) {
 267                continue;
 268            }
 269
 270            type_initialize_interface(ti, ti->interfaces[i].typename);
 271        }
 272    }
 273
 274    ti->class->type = ti;
 275
 276    while (parent) {
 277        if (parent->class_base_init) {
 278            parent->class_base_init(ti->class, ti->class_data);
 279        }
 280        parent = type_get_parent(parent);
 281    }
 282
 283    if (ti->class_init) {
 284        ti->class_init(ti->class, ti->class_data);
 285    }
 286
 287
 288}
 289
 290static void object_init_with_type(Object *obj, TypeImpl *ti)
 291{
 292    if (type_has_parent(ti)) {
 293        object_init_with_type(obj, type_get_parent(ti));
 294    }
 295
 296    if (ti->instance_init) {
 297        ti->instance_init(obj);
 298    }
 299}
 300
 301void object_initialize_with_type(void *data, TypeImpl *type)
 302{
 303    Object *obj = data;
 304
 305    g_assert(type != NULL);
 306    type_initialize(type);
 307
 308    g_assert(type->instance_size >= sizeof(Object));
 309    g_assert(type->abstract == false);
 310
 311    memset(obj, 0, type->instance_size);
 312    obj->class = type->class;
 313    object_ref(obj);
 314    QTAILQ_INIT(&obj->properties);
 315    object_init_with_type(obj, type);
 316}
 317
 318void object_initialize(void *data, const char *typename)
 319{
 320    TypeImpl *type = type_get_by_name(typename);
 321
 322    object_initialize_with_type(data, type);
 323}
 324
 325static inline bool object_property_is_child(ObjectProperty *prop)
 326{
 327    return strstart(prop->type, "child<", NULL);
 328}
 329
 330static inline bool object_property_is_link(ObjectProperty *prop)
 331{
 332    return strstart(prop->type, "link<", NULL);
 333}
 334
 335static void object_property_del_all(Object *obj)
 336{
 337    while (!QTAILQ_EMPTY(&obj->properties)) {
 338        ObjectProperty *prop = QTAILQ_FIRST(&obj->properties);
 339
 340        QTAILQ_REMOVE(&obj->properties, prop, node);
 341
 342        if (prop->release) {
 343            prop->release(obj, prop->name, prop->opaque);
 344        }
 345
 346        g_free(prop->name);
 347        g_free(prop->type);
 348        g_free(prop);
 349    }
 350}
 351
 352static void object_property_del_child(Object *obj, Object *child, Error **errp)
 353{
 354    ObjectProperty *prop;
 355
 356    QTAILQ_FOREACH(prop, &obj->properties, node) {
 357        if (object_property_is_child(prop) && prop->opaque == child) {
 358            object_property_del(obj, prop->name, errp);
 359            break;
 360        }
 361    }
 362}
 363
 364void object_unparent(Object *obj)
 365{
 366    if (!obj->parent) {
 367        return;
 368    }
 369
 370    object_ref(obj);
 371    if (obj->class->unparent) {
 372        (obj->class->unparent)(obj);
 373    }
 374    if (obj->parent) {
 375        object_property_del_child(obj->parent, obj, NULL);
 376    }
 377    object_unref(obj);
 378}
 379
 380static void object_deinit(Object *obj, TypeImpl *type)
 381{
 382    if (type->instance_finalize) {
 383        type->instance_finalize(obj);
 384    }
 385
 386    if (type_has_parent(type)) {
 387        object_deinit(obj, type_get_parent(type));
 388    }
 389}
 390
 391static void object_finalize(void *data)
 392{
 393    Object *obj = data;
 394    TypeImpl *ti = obj->class->type;
 395
 396    object_deinit(obj, ti);
 397    object_property_del_all(obj);
 398
 399    g_assert(obj->ref == 0);
 400    if (obj->free) {
 401        obj->free(obj);
 402    }
 403}
 404
 405Object *object_new_with_type(Type type)
 406{
 407    Object *obj;
 408
 409    g_assert(type != NULL);
 410    type_initialize(type);
 411
 412    obj = g_malloc(type->instance_size);
 413    object_initialize_with_type(obj, type);
 414    obj->free = g_free;
 415
 416    return obj;
 417}
 418
 419Object *object_new(const char *typename)
 420{
 421    TypeImpl *ti = type_get_by_name(typename);
 422
 423    return object_new_with_type(ti);
 424}
 425
 426Object *object_dynamic_cast(Object *obj, const char *typename)
 427{
 428    if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) {
 429        return obj;
 430    }
 431
 432    return NULL;
 433}
 434
 435Object *object_dynamic_cast_assert(Object *obj, const char *typename,
 436                                   const char *file, int line, const char *func)
 437{
 438    trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
 439                                     typename, file, line, func);
 440
 441#ifdef CONFIG_QOM_CAST_DEBUG
 442    int i;
 443    Object *inst;
 444
 445    for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) {
 446        if (obj->class->cast_cache[i] == typename) {
 447            goto out;
 448        }
 449    }
 450
 451    inst = object_dynamic_cast(obj, typename);
 452
 453    if (!inst && obj) {
 454        fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
 455                file, line, func, obj, typename);
 456        abort();
 457    }
 458
 459    assert(obj == inst);
 460
 461    if (obj == inst) {
 462        for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
 463            obj->class->cast_cache[i - 1] = obj->class->cast_cache[i];
 464        }
 465        obj->class->cast_cache[i - 1] = typename;
 466    }
 467
 468out:
 469#endif
 470    return obj;
 471}
 472
 473ObjectClass *object_class_dynamic_cast(ObjectClass *class,
 474                                       const char *typename)
 475{
 476    ObjectClass *ret = NULL;
 477    TypeImpl *target_type;
 478    TypeImpl *type;
 479
 480    if (!class) {
 481        return NULL;
 482    }
 483
 484    /* A simple fast path that can trigger a lot for leaf classes.  */
 485    type = class->type;
 486    if (type->name == typename) {
 487        return class;
 488    }
 489
 490    target_type = type_get_by_name(typename);
 491    if (!target_type) {
 492        /* target class type unknown, so fail the cast */
 493        return NULL;
 494    }
 495
 496    if (type->class->interfaces &&
 497            type_is_ancestor(target_type, type_interface)) {
 498        int found = 0;
 499        GSList *i;
 500
 501        for (i = class->interfaces; i; i = i->next) {
 502            ObjectClass *target_class = i->data;
 503
 504            if (type_is_ancestor(target_class->type, target_type)) {
 505                ret = target_class;
 506                found++;
 507            }
 508         }
 509
 510        /* The match was ambiguous, don't allow a cast */
 511        if (found > 1) {
 512            ret = NULL;
 513        }
 514    } else if (type_is_ancestor(type, target_type)) {
 515        ret = class;
 516    }
 517
 518    return ret;
 519}
 520
 521ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
 522                                              const char *typename,
 523                                              const char *file, int line,
 524                                              const char *func)
 525{
 526    ObjectClass *ret;
 527
 528    trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
 529                                           typename, file, line, func);
 530
 531#ifdef CONFIG_QOM_CAST_DEBUG
 532    int i;
 533
 534    for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) {
 535        if (class->cast_cache[i] == typename) {
 536            ret = class;
 537            goto out;
 538        }
 539    }
 540#else
 541    if (!class->interfaces) {
 542        return class;
 543    }
 544#endif
 545
 546    ret = object_class_dynamic_cast(class, typename);
 547    if (!ret && class) {
 548        fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
 549                file, line, func, class, typename);
 550        abort();
 551    }
 552
 553#ifdef CONFIG_QOM_CAST_DEBUG
 554    if (ret == class) {
 555        for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
 556            class->cast_cache[i - 1] = class->cast_cache[i];
 557        }
 558        class->cast_cache[i - 1] = typename;
 559    }
 560out:
 561#endif
 562    return ret;
 563}
 564
 565const char *object_get_typename(Object *obj)
 566{
 567    return obj->class->type->name;
 568}
 569
 570ObjectClass *object_get_class(Object *obj)
 571{
 572    return obj->class;
 573}
 574
 575bool object_class_is_abstract(ObjectClass *klass)
 576{
 577    return klass->type->abstract;
 578}
 579
 580const char *object_class_get_name(ObjectClass *klass)
 581{
 582    return klass->type->name;
 583}
 584
 585ObjectClass *object_class_by_name(const char *typename)
 586{
 587    TypeImpl *type = type_get_by_name(typename);
 588
 589    if (!type) {
 590        return NULL;
 591    }
 592
 593    type_initialize(type);
 594
 595    return type->class;
 596}
 597
 598ObjectClass *object_class_get_parent(ObjectClass *class)
 599{
 600    TypeImpl *type = type_get_parent(class->type);
 601
 602    if (!type) {
 603        return NULL;
 604    }
 605
 606    type_initialize(type);
 607
 608    return type->class;
 609}
 610
 611typedef struct OCFData
 612{
 613    void (*fn)(ObjectClass *klass, void *opaque);
 614    const char *implements_type;
 615    bool include_abstract;
 616    void *opaque;
 617} OCFData;
 618
 619static void object_class_foreach_tramp(gpointer key, gpointer value,
 620                                       gpointer opaque)
 621{
 622    OCFData *data = opaque;
 623    TypeImpl *type = value;
 624    ObjectClass *k;
 625
 626    type_initialize(type);
 627    k = type->class;
 628
 629    if (!data->include_abstract && type->abstract) {
 630        return;
 631    }
 632
 633    if (data->implements_type && 
 634        !object_class_dynamic_cast(k, data->implements_type)) {
 635        return;
 636    }
 637
 638    data->fn(k, data->opaque);
 639}
 640
 641void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
 642                          const char *implements_type, bool include_abstract,
 643                          void *opaque)
 644{
 645    OCFData data = { fn, implements_type, include_abstract, opaque };
 646
 647    g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
 648}
 649
 650int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
 651                         void *opaque)
 652{
 653    ObjectProperty *prop;
 654    int ret = 0;
 655
 656    QTAILQ_FOREACH(prop, &obj->properties, node) {
 657        if (object_property_is_child(prop)) {
 658            ret = fn(prop->opaque, opaque);
 659            if (ret != 0) {
 660                break;
 661            }
 662        }
 663    }
 664    return ret;
 665}
 666
 667static void object_class_get_list_tramp(ObjectClass *klass, void *opaque)
 668{
 669    GSList **list = opaque;
 670
 671    *list = g_slist_prepend(*list, klass);
 672}
 673
 674GSList *object_class_get_list(const char *implements_type,
 675                              bool include_abstract)
 676{
 677    GSList *list = NULL;
 678
 679    object_class_foreach(object_class_get_list_tramp,
 680                         implements_type, include_abstract, &list);
 681    return list;
 682}
 683
 684void object_ref(Object *obj)
 685{
 686    obj->ref++;
 687}
 688
 689void object_unref(Object *obj)
 690{
 691    g_assert(obj->ref > 0);
 692    obj->ref--;
 693
 694    /* parent always holds a reference to its children */
 695    if (obj->ref == 0) {
 696        object_finalize(obj);
 697    }
 698}
 699
 700void object_property_add(Object *obj, const char *name, const char *type,
 701                         ObjectPropertyAccessor *get,
 702                         ObjectPropertyAccessor *set,
 703                         ObjectPropertyRelease *release,
 704                         void *opaque, Error **errp)
 705{
 706    ObjectProperty *prop;
 707
 708    QTAILQ_FOREACH(prop, &obj->properties, node) {
 709        if (strcmp(prop->name, name) == 0) {
 710            error_setg(errp, "attempt to add duplicate property '%s'"
 711                       " to object (type '%s')", name,
 712                       object_get_typename(obj));
 713            return;
 714        }
 715    }
 716
 717    prop = g_malloc0(sizeof(*prop));
 718
 719    prop->name = g_strdup(name);
 720    prop->type = g_strdup(type);
 721
 722    prop->get = get;
 723    prop->set = set;
 724    prop->release = release;
 725    prop->opaque = opaque;
 726
 727    QTAILQ_INSERT_TAIL(&obj->properties, prop, node);
 728}
 729
 730ObjectProperty *object_property_find(Object *obj, const char *name,
 731                                     Error **errp)
 732{
 733    ObjectProperty *prop;
 734
 735    QTAILQ_FOREACH(prop, &obj->properties, node) {
 736        if (strcmp(prop->name, name) == 0) {
 737            return prop;
 738        }
 739    }
 740
 741    error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
 742    return NULL;
 743}
 744
 745void object_property_del(Object *obj, const char *name, Error **errp)
 746{
 747    ObjectProperty *prop = object_property_find(obj, name, errp);
 748    if (prop == NULL) {
 749        return;
 750    }
 751
 752    if (prop->release) {
 753        prop->release(obj, name, prop->opaque);
 754    }
 755
 756    QTAILQ_REMOVE(&obj->properties, prop, node);
 757
 758    g_free(prop->name);
 759    g_free(prop->type);
 760    g_free(prop);
 761}
 762
 763void object_property_get(Object *obj, Visitor *v, const char *name,
 764                         Error **errp)
 765{
 766    ObjectProperty *prop = object_property_find(obj, name, errp);
 767    if (prop == NULL) {
 768        return;
 769    }
 770
 771    if (!prop->get) {
 772        error_set(errp, QERR_PERMISSION_DENIED);
 773    } else {
 774        prop->get(obj, v, prop->opaque, name, errp);
 775    }
 776}
 777
 778void object_property_set(Object *obj, Visitor *v, const char *name,
 779                         Error **errp)
 780{
 781    ObjectProperty *prop = object_property_find(obj, name, errp);
 782    if (prop == NULL) {
 783        return;
 784    }
 785
 786    if (!prop->set) {
 787        error_set(errp, QERR_PERMISSION_DENIED);
 788    } else {
 789        prop->set(obj, v, prop->opaque, name, errp);
 790    }
 791}
 792
 793void object_property_set_str(Object *obj, const char *value,
 794                             const char *name, Error **errp)
 795{
 796    QString *qstr = qstring_from_str(value);
 797    object_property_set_qobject(obj, QOBJECT(qstr), name, errp);
 798
 799    QDECREF(qstr);
 800}
 801
 802char *object_property_get_str(Object *obj, const char *name,
 803                              Error **errp)
 804{
 805    QObject *ret = object_property_get_qobject(obj, name, errp);
 806    QString *qstring;
 807    char *retval;
 808
 809    if (!ret) {
 810        return NULL;
 811    }
 812    qstring = qobject_to_qstring(ret);
 813    if (!qstring) {
 814        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
 815        retval = NULL;
 816    } else {
 817        retval = g_strdup(qstring_get_str(qstring));
 818    }
 819
 820    QDECREF(qstring);
 821    return retval;
 822}
 823
 824void object_property_set_link(Object *obj, Object *value,
 825                              const char *name, Error **errp)
 826{
 827    object_property_set_str(obj, object_get_canonical_path(value),
 828                            name, errp);
 829}
 830
 831Object *object_property_get_link(Object *obj, const char *name,
 832                                 Error **errp)
 833{
 834    char *str = object_property_get_str(obj, name, errp);
 835    Object *target = NULL;
 836
 837    if (str && *str) {
 838        target = object_resolve_path(str, NULL);
 839        if (!target) {
 840            error_set(errp, QERR_DEVICE_NOT_FOUND, str);
 841        }
 842    }
 843
 844    g_free(str);
 845    return target;
 846}
 847
 848void object_property_set_bool(Object *obj, bool value,
 849                              const char *name, Error **errp)
 850{
 851    QBool *qbool = qbool_from_int(value);
 852    object_property_set_qobject(obj, QOBJECT(qbool), name, errp);
 853
 854    QDECREF(qbool);
 855}
 856
 857bool object_property_get_bool(Object *obj, const char *name,
 858                              Error **errp)
 859{
 860    QObject *ret = object_property_get_qobject(obj, name, errp);
 861    QBool *qbool;
 862    bool retval;
 863
 864    if (!ret) {
 865        return false;
 866    }
 867    qbool = qobject_to_qbool(ret);
 868    if (!qbool) {
 869        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
 870        retval = false;
 871    } else {
 872        retval = qbool_get_int(qbool);
 873    }
 874
 875    QDECREF(qbool);
 876    return retval;
 877}
 878
 879void object_property_set_int(Object *obj, int64_t value,
 880                             const char *name, Error **errp)
 881{
 882    QInt *qint = qint_from_int(value);
 883    object_property_set_qobject(obj, QOBJECT(qint), name, errp);
 884
 885    QDECREF(qint);
 886}
 887
 888int64_t object_property_get_int(Object *obj, const char *name,
 889                                Error **errp)
 890{
 891    QObject *ret = object_property_get_qobject(obj, name, errp);
 892    QInt *qint;
 893    int64_t retval;
 894
 895    if (!ret) {
 896        return -1;
 897    }
 898    qint = qobject_to_qint(ret);
 899    if (!qint) {
 900        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
 901        retval = -1;
 902    } else {
 903        retval = qint_get_int(qint);
 904    }
 905
 906    QDECREF(qint);
 907    return retval;
 908}
 909
 910void object_property_parse(Object *obj, const char *string,
 911                           const char *name, Error **errp)
 912{
 913    StringInputVisitor *mi;
 914    mi = string_input_visitor_new(string);
 915    object_property_set(obj, string_input_get_visitor(mi), name, errp);
 916
 917    string_input_visitor_cleanup(mi);
 918}
 919
 920char *object_property_print(Object *obj, const char *name,
 921                            Error **errp)
 922{
 923    StringOutputVisitor *mo;
 924    char *string;
 925
 926    mo = string_output_visitor_new();
 927    object_property_get(obj, string_output_get_visitor(mo), name, errp);
 928    string = string_output_get_string(mo);
 929    string_output_visitor_cleanup(mo);
 930    return string;
 931}
 932
 933const char *object_property_get_type(Object *obj, const char *name, Error **errp)
 934{
 935    ObjectProperty *prop = object_property_find(obj, name, errp);
 936    if (prop == NULL) {
 937        return NULL;
 938    }
 939
 940    return prop->type;
 941}
 942
 943Object *object_get_root(void)
 944{
 945    static Object *root;
 946
 947    if (!root) {
 948        root = object_new("container");
 949    }
 950
 951    return root;
 952}
 953
 954static void object_get_child_property(Object *obj, Visitor *v, void *opaque,
 955                                      const char *name, Error **errp)
 956{
 957    Object *child = opaque;
 958    gchar *path;
 959
 960    path = object_get_canonical_path(child);
 961    visit_type_str(v, &path, name, errp);
 962    g_free(path);
 963}
 964
 965static void object_finalize_child_property(Object *obj, const char *name,
 966                                           void *opaque)
 967{
 968    Object *child = opaque;
 969
 970    object_unref(child);
 971}
 972
 973void object_property_add_child(Object *obj, const char *name,
 974                               Object *child, Error **errp)
 975{
 976    gchar *type;
 977
 978    type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
 979
 980    object_property_add(obj, name, type, object_get_child_property,
 981                        NULL, object_finalize_child_property, child, errp);
 982
 983    object_ref(child);
 984    g_assert(child->parent == NULL);
 985    child->parent = obj;
 986
 987    g_free(type);
 988}
 989
 990static void object_get_link_property(Object *obj, Visitor *v, void *opaque,
 991                                     const char *name, Error **errp)
 992{
 993    Object **child = opaque;
 994    gchar *path;
 995
 996    if (*child) {
 997        path = object_get_canonical_path(*child);
 998        visit_type_str(v, &path, name, errp);
 999        g_free(path);
1000    } else {
1001        path = (gchar *)"";
1002        visit_type_str(v, &path, name, errp);
1003    }
1004}
1005
1006static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
1007                                     const char *name, Error **errp)
1008{
1009    Object **child = opaque;
1010    Object *old_target;
1011    bool ambiguous = false;
1012    const char *type;
1013    char *path;
1014    gchar *target_type;
1015
1016    type = object_property_get_type(obj, name, NULL);
1017
1018    visit_type_str(v, &path, name, errp);
1019
1020    old_target = *child;
1021    *child = NULL;
1022
1023    if (strcmp(path, "") != 0) {
1024        Object *target;
1025
1026        /* Go from link<FOO> to FOO.  */
1027        target_type = g_strndup(&type[5], strlen(type) - 6);
1028        target = object_resolve_path_type(path, target_type, &ambiguous);
1029
1030        if (ambiguous) {
1031            error_set(errp, QERR_AMBIGUOUS_PATH, path);
1032        } else if (target) {
1033            object_ref(target);
1034            *child = target;
1035        } else {
1036            target = object_resolve_path(path, &ambiguous);
1037            if (target || ambiguous) {
1038                error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
1039            } else {
1040                error_set(errp, QERR_DEVICE_NOT_FOUND, path);
1041            }
1042        }
1043        g_free(target_type);
1044    }
1045
1046    g_free(path);
1047
1048    if (old_target != NULL) {
1049        object_unref(old_target);
1050    }
1051}
1052
1053void object_property_add_link(Object *obj, const char *name,
1054                              const char *type, Object **child,
1055                              Error **errp)
1056{
1057    gchar *full_type;
1058
1059    full_type = g_strdup_printf("link<%s>", type);
1060
1061    object_property_add(obj, name, full_type,
1062                        object_get_link_property,
1063                        object_set_link_property,
1064                        NULL, child, errp);
1065
1066    g_free(full_type);
1067}
1068
1069gchar *object_get_canonical_path(Object *obj)
1070{
1071    Object *root = object_get_root();
1072    char *newpath = NULL, *path = NULL;
1073
1074    while (obj != root) {
1075        ObjectProperty *prop = NULL;
1076
1077        g_assert(obj->parent != NULL);
1078
1079        QTAILQ_FOREACH(prop, &obj->parent->properties, node) {
1080            if (!object_property_is_child(prop)) {
1081                continue;
1082            }
1083
1084            if (prop->opaque == obj) {
1085                if (path) {
1086                    newpath = g_strdup_printf("%s/%s", prop->name, path);
1087                    g_free(path);
1088                    path = newpath;
1089                } else {
1090                    path = g_strdup(prop->name);
1091                }
1092                break;
1093            }
1094        }
1095
1096        g_assert(prop != NULL);
1097
1098        obj = obj->parent;
1099    }
1100
1101    newpath = g_strdup_printf("/%s", path);
1102    g_free(path);
1103
1104    return newpath;
1105}
1106
1107Object *object_resolve_path_component(Object *parent, const gchar *part)
1108{
1109    ObjectProperty *prop = object_property_find(parent, part, NULL);
1110    if (prop == NULL) {
1111        return NULL;
1112    }
1113
1114    if (object_property_is_link(prop)) {
1115        return *(Object **)prop->opaque;
1116    } else if (object_property_is_child(prop)) {
1117        return prop->opaque;
1118    } else {
1119        return NULL;
1120    }
1121}
1122
1123static Object *object_resolve_abs_path(Object *parent,
1124                                          gchar **parts,
1125                                          const char *typename,
1126                                          int index)
1127{
1128    Object *child;
1129
1130    if (parts[index] == NULL) {
1131        return object_dynamic_cast(parent, typename);
1132    }
1133
1134    if (strcmp(parts[index], "") == 0) {
1135        return object_resolve_abs_path(parent, parts, typename, index + 1);
1136    }
1137
1138    child = object_resolve_path_component(parent, parts[index]);
1139    if (!child) {
1140        return NULL;
1141    }
1142
1143    return object_resolve_abs_path(child, parts, typename, index + 1);
1144}
1145
1146static Object *object_resolve_partial_path(Object *parent,
1147                                              gchar **parts,
1148                                              const char *typename,
1149                                              bool *ambiguous)
1150{
1151    Object *obj;
1152    ObjectProperty *prop;
1153
1154    obj = object_resolve_abs_path(parent, parts, typename, 0);
1155
1156    QTAILQ_FOREACH(prop, &parent->properties, node) {
1157        Object *found;
1158
1159        if (!object_property_is_child(prop)) {
1160            continue;
1161        }
1162
1163        found = object_resolve_partial_path(prop->opaque, parts,
1164                                            typename, ambiguous);
1165        if (found) {
1166            if (obj) {
1167                if (ambiguous) {
1168                    *ambiguous = true;
1169                }
1170                return NULL;
1171            }
1172            obj = found;
1173        }
1174
1175        if (ambiguous && *ambiguous) {
1176            return NULL;
1177        }
1178    }
1179
1180    return obj;
1181}
1182
1183Object *object_resolve_path_type(const char *path, const char *typename,
1184                                 bool *ambiguous)
1185{
1186    Object *obj;
1187    gchar **parts;
1188
1189    parts = g_strsplit(path, "/", 0);
1190    assert(parts);
1191
1192    if (parts[0] == NULL || strcmp(parts[0], "") != 0) {
1193        if (ambiguous) {
1194            *ambiguous = false;
1195        }
1196        obj = object_resolve_partial_path(object_get_root(), parts,
1197                                          typename, ambiguous);
1198    } else {
1199        obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
1200    }
1201
1202    g_strfreev(parts);
1203
1204    return obj;
1205}
1206
1207Object *object_resolve_path(const char *path, bool *ambiguous)
1208{
1209    return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
1210}
1211
1212typedef struct StringProperty
1213{
1214    char *(*get)(Object *, Error **);
1215    void (*set)(Object *, const char *, Error **);
1216} StringProperty;
1217
1218static void property_get_str(Object *obj, Visitor *v, void *opaque,
1219                             const char *name, Error **errp)
1220{
1221    StringProperty *prop = opaque;
1222    char *value;
1223
1224    value = prop->get(obj, errp);
1225    if (value) {
1226        visit_type_str(v, &value, name, errp);
1227        g_free(value);
1228    }
1229}
1230
1231static void property_set_str(Object *obj, Visitor *v, void *opaque,
1232                             const char *name, Error **errp)
1233{
1234    StringProperty *prop = opaque;
1235    char *value;
1236    Error *local_err = NULL;
1237
1238    visit_type_str(v, &value, name, &local_err);
1239    if (local_err) {
1240        error_propagate(errp, local_err);
1241        return;
1242    }
1243
1244    prop->set(obj, value, errp);
1245    g_free(value);
1246}
1247
1248static void property_release_str(Object *obj, const char *name,
1249                                 void *opaque)
1250{
1251    StringProperty *prop = opaque;
1252    g_free(prop);
1253}
1254
1255void object_property_add_str(Object *obj, const char *name,
1256                           char *(*get)(Object *, Error **),
1257                           void (*set)(Object *, const char *, Error **),
1258                           Error **errp)
1259{
1260    StringProperty *prop = g_malloc0(sizeof(*prop));
1261
1262    prop->get = get;
1263    prop->set = set;
1264
1265    object_property_add(obj, name, "string",
1266                        get ? property_get_str : NULL,
1267                        set ? property_set_str : NULL,
1268                        property_release_str,
1269                        prop, errp);
1270}
1271
1272typedef struct BoolProperty
1273{
1274    bool (*get)(Object *, Error **);
1275    void (*set)(Object *, bool, Error **);
1276} BoolProperty;
1277
1278static void property_get_bool(Object *obj, Visitor *v, void *opaque,
1279                              const char *name, Error **errp)
1280{
1281    BoolProperty *prop = opaque;
1282    bool value;
1283
1284    value = prop->get(obj, errp);
1285    visit_type_bool(v, &value, name, errp);
1286}
1287
1288static void property_set_bool(Object *obj, Visitor *v, void *opaque,
1289                              const char *name, Error **errp)
1290{
1291    BoolProperty *prop = opaque;
1292    bool value;
1293    Error *local_err = NULL;
1294
1295    visit_type_bool(v, &value, name, &local_err);
1296    if (local_err) {
1297        error_propagate(errp, local_err);
1298        return;
1299    }
1300
1301    prop->set(obj, value, errp);
1302}
1303
1304static void property_release_bool(Object *obj, const char *name,
1305                                  void *opaque)
1306{
1307    BoolProperty *prop = opaque;
1308    g_free(prop);
1309}
1310
1311void object_property_add_bool(Object *obj, const char *name,
1312                              bool (*get)(Object *, Error **),
1313                              void (*set)(Object *, bool, Error **),
1314                              Error **errp)
1315{
1316    BoolProperty *prop = g_malloc0(sizeof(*prop));
1317
1318    prop->get = get;
1319    prop->set = set;
1320
1321    object_property_add(obj, name, "bool",
1322                        get ? property_get_bool : NULL,
1323                        set ? property_set_bool : NULL,
1324                        property_release_bool,
1325                        prop, errp);
1326}
1327
1328static char *qdev_get_type(Object *obj, Error **errp)
1329{
1330    return g_strdup(object_get_typename(obj));
1331}
1332
1333static void object_instance_init(Object *obj)
1334{
1335    object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
1336}
1337
1338static void register_types(void)
1339{
1340    static TypeInfo interface_info = {
1341        .name = TYPE_INTERFACE,
1342        .class_size = sizeof(InterfaceClass),
1343        .abstract = true,
1344    };
1345
1346    static TypeInfo object_info = {
1347        .name = TYPE_OBJECT,
1348        .instance_size = sizeof(Object),
1349        .instance_init = object_instance_init,
1350        .abstract = true,
1351    };
1352
1353    type_interface = type_register_internal(&interface_info);
1354    type_register_internal(&object_info);
1355}
1356
1357type_init(register_types)
1358