Statistics
| Branch: | Revision:

root / qom / object.c @ 371c6489

History | View | Annotate | Download (27.5 kB)

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 "qemu/object.h"
14
#include "qemu-common.h"
15
#include "qapi/qapi-visit-core.h"
16
#include "qapi/string-input-visitor.h"
17
#include "qapi/string-output-visitor.h"
18

    
19
/* TODO: replace QObject with a simpler visitor to avoid a dependency
20
 * of the QOM core on QObject?  */
21
#include "qemu/qom-qobject.h"
22
#include "qobject.h"
23
#include "qbool.h"
24
#include "qint.h"
25
#include "qstring.h"
26

    
27
#define MAX_INTERFACES 32
28

    
29
typedef struct InterfaceImpl InterfaceImpl;
30
typedef struct TypeImpl TypeImpl;
31

    
32
struct InterfaceImpl
33
{
34
    const char *parent;
35
    void (*interface_initfn)(ObjectClass *class, void *data);
36
    TypeImpl *type;
37
};
38

    
39
struct 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_finalize)(ObjectClass *klass, void *data);
49

    
50
    void *class_data;
51

    
52
    void (*instance_init)(Object *obj);
53
    void (*instance_finalize)(Object *obj);
54

    
55
    bool abstract;
56

    
57
    const char *parent;
58
    TypeImpl *parent_type;
59

    
60
    ObjectClass *class;
61

    
62
    int num_interfaces;
63
    InterfaceImpl interfaces[MAX_INTERFACES];
64
};
65

    
66
typedef struct Interface
67
{
68
    Object parent;
69
    Object *obj;
70
} Interface;
71

    
72
#define INTERFACE(obj) OBJECT_CHECK(Interface, obj, TYPE_INTERFACE)
73

    
74
static Type type_interface;
75

    
76
static GHashTable *type_table_get(void)
77
{
78
    static GHashTable *type_table;
79

    
80
    if (type_table == NULL) {
81
        type_table = g_hash_table_new(g_str_hash, g_str_equal);
82
    }
83

    
84
    return type_table;
85
}
86

    
87
static void type_table_add(TypeImpl *ti)
88
{
89
    g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
90
}
91

    
92
static TypeImpl *type_table_lookup(const char *name)
93
{
94
    return g_hash_table_lookup(type_table_get(), name);
95
}
96

    
97
TypeImpl *type_register(const TypeInfo *info)
98
{
99
    TypeImpl *ti = g_malloc0(sizeof(*ti));
100

    
101
    g_assert(info->name != NULL);
102

    
103
    if (type_table_lookup(info->name) != NULL) {
104
        fprintf(stderr, "Registering `%s' which already exists\n", info->name);
105
        abort();
106
    }
107

    
108
    ti->name = g_strdup(info->name);
109
    ti->parent = g_strdup(info->parent);
110

    
111
    ti->class_size = info->class_size;
112
    ti->instance_size = info->instance_size;
113

    
114
    ti->class_init = info->class_init;
115
    ti->class_finalize = info->class_finalize;
116
    ti->class_data = info->class_data;
117

    
118
    ti->instance_init = info->instance_init;
119
    ti->instance_finalize = info->instance_finalize;
120

    
121
    ti->abstract = info->abstract;
122

    
123
    if (info->interfaces) {
124
        int i;
125

    
126
        for (i = 0; info->interfaces[i].type; i++) {
127
            ti->interfaces[i].parent = info->interfaces[i].type;
128
            ti->interfaces[i].interface_initfn = info->interfaces[i].interface_initfn;
129
            ti->num_interfaces++;
130
        }
131
    }
132

    
133
    type_table_add(ti);
134

    
135
    return ti;
136
}
137

    
138
TypeImpl *type_register_static(const TypeInfo *info)
139
{
140
    return type_register(info);
141
}
142

    
143
static TypeImpl *type_get_by_name(const char *name)
144
{
145
    if (name == NULL) {
146
        return NULL;
147
    }
148

    
149
    return type_table_lookup(name);
150
}
151

    
152
static TypeImpl *type_get_parent(TypeImpl *type)
153
{
154
    if (!type->parent_type && type->parent) {
155
        type->parent_type = type_get_by_name(type->parent);
156
        g_assert(type->parent_type != NULL);
157
    }
158

    
159
    return type->parent_type;
160
}
161

    
162
static bool type_has_parent(TypeImpl *type)
163
{
164
    return (type->parent != NULL);
165
}
166

    
167
static size_t type_class_get_size(TypeImpl *ti)
168
{
169
    if (ti->class_size) {
170
        return ti->class_size;
171
    }
172

    
173
    if (type_has_parent(ti)) {
174
        return type_class_get_size(type_get_parent(ti));
175
    }
176

    
177
    return sizeof(ObjectClass);
178
}
179

    
180
static void type_class_interface_init(TypeImpl *ti, InterfaceImpl *iface)
181
{
182
    TypeInfo info = {
183
        .instance_size = sizeof(Interface),
184
        .parent = iface->parent,
185
        .class_size = sizeof(InterfaceClass),
186
        .class_init = iface->interface_initfn,
187
        .abstract = true,
188
    };
189
    char *name = g_strdup_printf("<%s::%s>", ti->name, iface->parent);
190

    
191
    info.name = name;
192
    iface->type = type_register(&info);
193
    g_free(name);
194
}
195

    
196
static void type_class_init(TypeImpl *ti)
197
{
198
    size_t class_size = sizeof(ObjectClass);
199
    int i;
200

    
201
    if (ti->class) {
202
        return;
203
    }
204

    
205
    ti->class_size = type_class_get_size(ti);
206

    
207
    ti->class = g_malloc0(ti->class_size);
208
    ti->class->type = ti;
209

    
210
    if (type_has_parent(ti)) {
211
        TypeImpl *parent = type_get_parent(ti);
212

    
213
        type_class_init(parent);
214

    
215
        class_size = parent->class_size;
216
        g_assert(parent->class_size <= ti->class_size);
217

    
218
        memcpy((void *)ti->class + sizeof(ObjectClass),
219
               (void *)parent->class + sizeof(ObjectClass),
220
               parent->class_size - sizeof(ObjectClass));
221
    }
222

    
223
    memset((void *)ti->class + class_size, 0, ti->class_size - class_size);
224

    
225
    for (i = 0; i < ti->num_interfaces; i++) {
226
        type_class_interface_init(ti, &ti->interfaces[i]);
227
    }
228

    
229
    if (ti->class_init) {
230
        ti->class_init(ti->class, ti->class_data);
231
    }
232
}
233

    
234
static void object_interface_init(Object *obj, InterfaceImpl *iface)
235
{
236
    TypeImpl *ti = iface->type;
237
    Interface *iface_obj;
238

    
239
    iface_obj = INTERFACE(object_new(ti->name));
240
    iface_obj->obj = obj;
241

    
242
    obj->interfaces = g_slist_prepend(obj->interfaces, iface_obj);
243
}
244

    
245
static void object_init_with_type(Object *obj, TypeImpl *ti)
246
{
247
    int i;
248

    
249
    if (type_has_parent(ti)) {
250
        object_init_with_type(obj, type_get_parent(ti));
251
    }
252

    
253
    for (i = 0; i < ti->num_interfaces; i++) {
254
        object_interface_init(obj, &ti->interfaces[i]);
255
    }
256

    
257
    if (ti->instance_init) {
258
        ti->instance_init(obj);
259
    }
260
}
261

    
262
void object_initialize_with_type(void *data, TypeImpl *type)
263
{
264
    Object *obj = data;
265

    
266
    g_assert(type != NULL);
267
    g_assert(type->instance_size >= sizeof(Object));
268

    
269
    type_class_init(type);
270
    g_assert(type->abstract == false);
271

    
272
    memset(obj, 0, type->instance_size);
273
    obj->class = type->class;
274
    QTAILQ_INIT(&obj->properties);
275
    object_init_with_type(obj, type);
276
}
277

    
278
void object_initialize(void *data, const char *typename)
279
{
280
    TypeImpl *type = type_get_by_name(typename);
281

    
282
    object_initialize_with_type(data, type);
283
}
284

    
285
static void object_property_del_all(Object *obj)
286
{
287
    while (!QTAILQ_EMPTY(&obj->properties)) {
288
        ObjectProperty *prop = QTAILQ_FIRST(&obj->properties);
289

    
290
        QTAILQ_REMOVE(&obj->properties, prop, node);
291

    
292
        if (prop->release) {
293
            prop->release(obj, prop->name, prop->opaque);
294
        }
295

    
296
        g_free(prop->name);
297
        g_free(prop->type);
298
        g_free(prop);
299
    }
300
}
301

    
302
static void object_property_del_child(Object *obj, Object *child, Error **errp)
303
{
304
    ObjectProperty *prop;
305

    
306
    QTAILQ_FOREACH(prop, &obj->properties, node) {
307
        if (!strstart(prop->type, "child<", NULL)) {
308
            continue;
309
        }
310

    
311
        if (prop->opaque == child) {
312
            object_property_del(obj, prop->name, errp);
313
        }
314
    }
315
}
316

    
317
void object_unparent(Object *obj)
318
{
319
    if (obj->parent) {
320
        object_property_del_child(obj->parent, obj, NULL);
321
    }
322
}
323

    
324
static void object_deinit(Object *obj, TypeImpl *type)
325
{
326
    if (type->instance_finalize) {
327
        type->instance_finalize(obj);
328
    }
329

    
330
    while (obj->interfaces) {
331
        Interface *iface_obj = obj->interfaces->data;
332
        obj->interfaces = g_slist_delete_link(obj->interfaces, obj->interfaces);
333
        object_delete(OBJECT(iface_obj));
334
    }
335

    
336
    if (type_has_parent(type)) {
337
        object_deinit(obj, type_get_parent(type));
338
    }
339

    
340
    object_unparent(obj);
341
}
342

    
343
void object_finalize(void *data)
344
{
345
    Object *obj = data;
346
    TypeImpl *ti = obj->class->type;
347

    
348
    object_deinit(obj, ti);
349
    object_property_del_all(obj);
350

    
351
    g_assert(obj->ref == 0);
352
}
353

    
354
Object *object_new_with_type(Type type)
355
{
356
    Object *obj;
357

    
358
    g_assert(type != NULL);
359

    
360
    obj = g_malloc(type->instance_size);
361
    object_initialize_with_type(obj, type);
362
    object_ref(obj);
363

    
364
    return obj;
365
}
366

    
367
Object *object_new(const char *typename)
368
{
369
    TypeImpl *ti = type_get_by_name(typename);
370

    
371
    return object_new_with_type(ti);
372
}
373

    
374
void object_delete(Object *obj)
375
{
376
    object_unref(obj);
377
    g_assert(obj->ref == 0);
378
    g_free(obj);
379
}
380

    
381
static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
382
{
383
    assert(target_type);
384

    
385
    /* Check if typename is a direct ancestor of type */
386
    while (type) {
387
        if (type == target_type) {
388
            return true;
389
        }
390

    
391
        type = type_get_parent(type);
392
    }
393

    
394
    return false;
395
}
396

    
397
static bool object_is_type(Object *obj, TypeImpl *target_type)
398
{
399
    return !target_type || type_is_ancestor(obj->class->type, target_type);
400
}
401

    
402
Object *object_dynamic_cast(Object *obj, const char *typename)
403
{
404
    TypeImpl *target_type = type_get_by_name(typename);
405
    GSList *i;
406

    
407
    /* Check if typename is a direct ancestor.  Special-case TYPE_OBJECT,
408
     * we want to go back from interfaces to the parent.
409
    */
410
    if (target_type && object_is_type(obj, target_type)) {
411
        return obj;
412
    }
413

    
414
    /* Check if obj is an interface and its containing object is a direct
415
     * ancestor of typename.  In principle we could do this test at the very
416
     * beginning of object_dynamic_cast, avoiding a second call to
417
     * object_is_type.  However, casting between interfaces is relatively
418
     * rare, and object_is_type(obj, type_interface) would fail almost always.
419
     *
420
     * Perhaps we could add a magic value to the object header for increased
421
     * (run-time) type safety and to speed up tests like this one.  If we ever
422
     * do that we can revisit the order here.
423
     */
424
    if (object_is_type(obj, type_interface)) {
425
        assert(!obj->interfaces);
426
        obj = INTERFACE(obj)->obj;
427
        if (object_is_type(obj, target_type)) {
428
            return obj;
429
        }
430
    }
431

    
432
    if (!target_type) {
433
        return obj;
434
    }
435

    
436
    /* Check if obj has an interface of typename */
437
    for (i = obj->interfaces; i; i = i->next) {
438
        Interface *iface = i->data;
439

    
440
        if (object_is_type(OBJECT(iface), target_type)) {
441
            return OBJECT(iface);
442
        }
443
    }
444

    
445
    return NULL;
446
}
447

    
448

    
449
static void register_types(void)
450
{
451
    static TypeInfo interface_info = {
452
        .name = TYPE_INTERFACE,
453
        .instance_size = sizeof(Interface),
454
        .abstract = true,
455
    };
456

    
457
    type_interface = type_register_static(&interface_info);
458
}
459

    
460
type_init(register_types)
461

    
462
Object *object_dynamic_cast_assert(Object *obj, const char *typename)
463
{
464
    Object *inst;
465

    
466
    inst = object_dynamic_cast(obj, typename);
467

    
468
    if (!inst) {
469
        fprintf(stderr, "Object %p is not an instance of type %s\n",
470
                obj, typename);
471
        abort();
472
    }
473

    
474
    return inst;
475
}
476

    
477
ObjectClass *object_class_dynamic_cast(ObjectClass *class,
478
                                       const char *typename)
479
{
480
    TypeImpl *target_type = type_get_by_name(typename);
481
    TypeImpl *type = class->type;
482

    
483
    while (type) {
484
        if (type == target_type) {
485
            return class;
486
        }
487

    
488
        type = type_get_parent(type);
489
    }
490

    
491
    return NULL;
492
}
493

    
494
ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
495
                                              const char *typename)
496
{
497
    ObjectClass *ret = object_class_dynamic_cast(class, typename);
498

    
499
    if (!ret) {
500
        fprintf(stderr, "Object %p is not an instance of type %s\n",
501
                class, typename);
502
        abort();
503
    }
504

    
505
    return ret;
506
}
507

    
508
const char *object_get_typename(Object *obj)
509
{
510
    return obj->class->type->name;
511
}
512

    
513
ObjectClass *object_get_class(Object *obj)
514
{
515
    return obj->class;
516
}
517

    
518
const char *object_class_get_name(ObjectClass *klass)
519
{
520
    return klass->type->name;
521
}
522

    
523
ObjectClass *object_class_by_name(const char *typename)
524
{
525
    TypeImpl *type = type_get_by_name(typename);
526

    
527
    if (!type) {
528
        return NULL;
529
    }
530

    
531
    type_class_init(type);
532

    
533
    return type->class;
534
}
535

    
536
typedef struct OCFData
537
{
538
    void (*fn)(ObjectClass *klass, void *opaque);
539
    const char *implements_type;
540
    bool include_abstract;
541
    void *opaque;
542
} OCFData;
543

    
544
static void object_class_foreach_tramp(gpointer key, gpointer value,
545
                                       gpointer opaque)
546
{
547
    OCFData *data = opaque;
548
    TypeImpl *type = value;
549
    ObjectClass *k;
550

    
551
    type_class_init(type);
552
    k = type->class;
553

    
554
    if (!data->include_abstract && type->abstract) {
555
        return;
556
    }
557

    
558
    if (data->implements_type && 
559
        !object_class_dynamic_cast(k, data->implements_type)) {
560
        return;
561
    }
562

    
563
    data->fn(k, data->opaque);
564
}
565

    
566
void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
567
                          const char *implements_type, bool include_abstract,
568
                          void *opaque)
569
{
570
    OCFData data = { fn, implements_type, include_abstract, opaque };
571

    
572
    g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
573
}
574

    
575
void object_ref(Object *obj)
576
{
577
    obj->ref++;
578
}
579

    
580
void object_unref(Object *obj)
581
{
582
    g_assert(obj->ref > 0);
583
    obj->ref--;
584

    
585
    /* parent always holds a reference to its children */
586
    if (obj->ref == 0) {
587
        object_finalize(obj);
588
    }
589
}
590

    
591
void object_property_add(Object *obj, const char *name, const char *type,
592
                         ObjectPropertyAccessor *get,
593
                         ObjectPropertyAccessor *set,
594
                         ObjectPropertyRelease *release,
595
                         void *opaque, Error **errp)
596
{
597
    ObjectProperty *prop = g_malloc0(sizeof(*prop));
598

    
599
    prop->name = g_strdup(name);
600
    prop->type = g_strdup(type);
601

    
602
    prop->get = get;
603
    prop->set = set;
604
    prop->release = release;
605
    prop->opaque = opaque;
606

    
607
    QTAILQ_INSERT_TAIL(&obj->properties, prop, node);
608
}
609

    
610
static ObjectProperty *object_property_find(Object *obj, const char *name)
611
{
612
    ObjectProperty *prop;
613

    
614
    QTAILQ_FOREACH(prop, &obj->properties, node) {
615
        if (strcmp(prop->name, name) == 0) {
616
            return prop;
617
        }
618
    }
619

    
620
    return NULL;
621
}
622

    
623
void object_property_del(Object *obj, const char *name, Error **errp)
624
{
625
    ObjectProperty *prop = object_property_find(obj, name);
626

    
627
    QTAILQ_REMOVE(&obj->properties, prop, node);
628

    
629
    prop->release(obj, prop->name, prop->opaque);
630

    
631
    g_free(prop->name);
632
    g_free(prop->type);
633
    g_free(prop);
634
}
635

    
636
void object_property_get(Object *obj, Visitor *v, const char *name,
637
                         Error **errp)
638
{
639
    ObjectProperty *prop = object_property_find(obj, name);
640

    
641
    if (prop == NULL) {
642
        error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
643
        return;
644
    }
645

    
646
    if (!prop->get) {
647
        error_set(errp, QERR_PERMISSION_DENIED);
648
    } else {
649
        prop->get(obj, v, prop->opaque, name, errp);
650
    }
651
}
652

    
653
void object_property_set(Object *obj, Visitor *v, const char *name,
654
                         Error **errp)
655
{
656
    ObjectProperty *prop = object_property_find(obj, name);
657

    
658
    if (prop == NULL) {
659
        error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
660
        return;
661
    }
662

    
663
    if (!prop->set) {
664
        error_set(errp, QERR_PERMISSION_DENIED);
665
    } else {
666
        prop->set(obj, v, prop->opaque, name, errp);
667
    }
668
}
669

    
670
void object_property_set_str(Object *obj, const char *value,
671
                             const char *name, Error **errp)
672
{
673
    QString *qstr = qstring_from_str(value);
674
    object_property_set_qobject(obj, QOBJECT(qstr), name, errp);
675

    
676
    QDECREF(qstr);
677
}
678

    
679
char *object_property_get_str(Object *obj, const char *name,
680
                              Error **errp)
681
{
682
    QObject *ret = object_property_get_qobject(obj, name, errp);
683
    QString *qstring;
684
    char *retval;
685

    
686
    if (!ret) {
687
        return NULL;
688
    }
689
    qstring = qobject_to_qstring(ret);
690
    if (!qstring) {
691
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
692
        retval = NULL;
693
    } else {
694
        retval = g_strdup(qstring_get_str(qstring));
695
    }
696

    
697
    QDECREF(qstring);
698
    return retval;
699
}
700

    
701
void object_property_set_link(Object *obj, Object *value,
702
                              const char *name, Error **errp)
703
{
704
    object_property_set_str(obj, object_get_canonical_path(value),
705
                            name, errp);
706
}
707

    
708
Object *object_property_get_link(Object *obj, const char *name,
709
                                 Error **errp)
710
{
711
    char *str = object_property_get_str(obj, name, errp);
712
    Object *target = NULL;
713

    
714
    if (str && *str) {
715
        target = object_resolve_path(str, NULL);
716
        if (!target) {
717
            error_set(errp, QERR_DEVICE_NOT_FOUND, str);
718
        }
719
    }
720

    
721
    g_free(str);
722
    return target;
723
}
724

    
725
void object_property_set_bool(Object *obj, bool value,
726
                              const char *name, Error **errp)
727
{
728
    QBool *qbool = qbool_from_int(value);
729
    object_property_set_qobject(obj, QOBJECT(qbool), name, errp);
730

    
731
    QDECREF(qbool);
732
}
733

    
734
bool object_property_get_bool(Object *obj, const char *name,
735
                              Error **errp)
736
{
737
    QObject *ret = object_property_get_qobject(obj, name, errp);
738
    QBool *qbool;
739
    bool retval;
740

    
741
    if (!ret) {
742
        return false;
743
    }
744
    qbool = qobject_to_qbool(ret);
745
    if (!qbool) {
746
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
747
        retval = false;
748
    } else {
749
        retval = qbool_get_int(qbool);
750
    }
751

    
752
    QDECREF(qbool);
753
    return retval;
754
}
755

    
756
void object_property_set_int(Object *obj, int64_t value,
757
                             const char *name, Error **errp)
758
{
759
    QInt *qint = qint_from_int(value);
760
    object_property_set_qobject(obj, QOBJECT(qint), name, errp);
761

    
762
    QDECREF(qint);
763
}
764

    
765
int64_t object_property_get_int(Object *obj, const char *name,
766
                                Error **errp)
767
{
768
    QObject *ret = object_property_get_qobject(obj, name, errp);
769
    QInt *qint;
770
    int64_t retval;
771

    
772
    if (!ret) {
773
        return -1;
774
    }
775
    qint = qobject_to_qint(ret);
776
    if (!qint) {
777
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
778
        retval = -1;
779
    } else {
780
        retval = qint_get_int(qint);
781
    }
782

    
783
    QDECREF(qint);
784
    return retval;
785
}
786

    
787
void object_property_parse(Object *obj, const char *string,
788
                           const char *name, Error **errp)
789
{
790
    StringInputVisitor *mi;
791
    mi = string_input_visitor_new(string);
792
    object_property_set(obj, string_input_get_visitor(mi), name, errp);
793

    
794
    string_input_visitor_cleanup(mi);
795
}
796

    
797
char *object_property_print(Object *obj, const char *name,
798
                            Error **errp)
799
{
800
    StringOutputVisitor *mo;
801
    char *string;
802

    
803
    mo = string_output_visitor_new();
804
    object_property_get(obj, string_output_get_visitor(mo), name, NULL);
805
    string = string_output_get_string(mo);
806
    string_output_visitor_cleanup(mo);
807
    return string;
808
}
809

    
810
const char *object_property_get_type(Object *obj, const char *name, Error **errp)
811
{
812
    ObjectProperty *prop = object_property_find(obj, name);
813

    
814
    if (prop == NULL) {
815
        error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
816
        return NULL;
817
    }
818

    
819
    return prop->type;
820
}
821

    
822
Object *object_get_root(void)
823
{
824
    static Object *root;
825

    
826
    if (!root) {
827
        root = object_new("container");
828
    }
829

    
830
    return root;
831
}
832

    
833
static void object_get_child_property(Object *obj, Visitor *v, void *opaque,
834
                                      const char *name, Error **errp)
835
{
836
    Object *child = opaque;
837
    gchar *path;
838

    
839
    path = object_get_canonical_path(child);
840
    visit_type_str(v, &path, name, errp);
841
    g_free(path);
842
}
843

    
844
static void object_finalize_child_property(Object *obj, const char *name,
845
                                           void *opaque)
846
{
847
    Object *child = opaque;
848

    
849
    object_unref(child);
850
}
851

    
852
void object_property_add_child(Object *obj, const char *name,
853
                               Object *child, Error **errp)
854
{
855
    gchar *type;
856

    
857
    /* Registering an interface object in the composition tree will mightily
858
     * confuse object_get_canonical_path (which, on the other hand, knows how
859
     * to get the canonical path of an interface object).
860
     */
861
    assert(!object_is_type(obj, type_interface));
862

    
863
    type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
864

    
865
    object_property_add(obj, name, type, object_get_child_property,
866
                        NULL, object_finalize_child_property, child, errp);
867

    
868
    object_ref(child);
869
    g_assert(child->parent == NULL);
870
    child->parent = obj;
871

    
872
    g_free(type);
873
}
874

    
875
static void object_get_link_property(Object *obj, Visitor *v, void *opaque,
876
                                     const char *name, Error **errp)
877
{
878
    Object **child = opaque;
879
    gchar *path;
880

    
881
    if (*child) {
882
        path = object_get_canonical_path(*child);
883
        visit_type_str(v, &path, name, errp);
884
        g_free(path);
885
    } else {
886
        path = (gchar *)"";
887
        visit_type_str(v, &path, name, errp);
888
    }
889
}
890

    
891
static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
892
                                     const char *name, Error **errp)
893
{
894
    Object **child = opaque;
895
    Object *old_target;
896
    bool ambiguous = false;
897
    const char *type;
898
    char *path;
899
    gchar *target_type;
900

    
901
    type = object_property_get_type(obj, name, NULL);
902

    
903
    visit_type_str(v, &path, name, errp);
904

    
905
    old_target = *child;
906
    *child = NULL;
907

    
908
    if (strcmp(path, "") != 0) {
909
        Object *target;
910

    
911
        /* Go from link<FOO> to FOO.  */
912
        target_type = g_strndup(&type[5], strlen(type) - 6);
913
        target = object_resolve_path_type(path, target_type, &ambiguous);
914

    
915
        if (ambiguous) {
916
            error_set(errp, QERR_AMBIGUOUS_PATH, path);
917
        } else if (target) {
918
            object_ref(target);
919
            *child = target;
920
        } else {
921
            target = object_resolve_path(path, &ambiguous);
922
            if (target || ambiguous) {
923
                error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
924
            } else {
925
                error_set(errp, QERR_DEVICE_NOT_FOUND, path);
926
            }
927
        }
928
        g_free(target_type);
929
    }
930

    
931
    g_free(path);
932

    
933
    if (old_target != NULL) {
934
        object_unref(old_target);
935
    }
936
}
937

    
938
void object_property_add_link(Object *obj, const char *name,
939
                              const char *type, Object **child,
940
                              Error **errp)
941
{
942
    gchar *full_type;
943

    
944
    full_type = g_strdup_printf("link<%s>", type);
945

    
946
    object_property_add(obj, name, full_type,
947
                        object_get_link_property,
948
                        object_set_link_property,
949
                        NULL, child, errp);
950

    
951
    g_free(full_type);
952
}
953

    
954
gchar *object_get_canonical_path(Object *obj)
955
{
956
    Object *root = object_get_root();
957
    char *newpath = NULL, *path = NULL;
958

    
959
    if (object_is_type(obj, type_interface)) {
960
        obj = INTERFACE(obj)->obj;
961
    }
962

    
963
    while (obj != root) {
964
        ObjectProperty *prop = NULL;
965

    
966
        g_assert(obj->parent != NULL);
967

    
968
        QTAILQ_FOREACH(prop, &obj->parent->properties, node) {
969
            if (!strstart(prop->type, "child<", NULL)) {
970
                continue;
971
            }
972

    
973
            if (prop->opaque == obj) {
974
                if (path) {
975
                    newpath = g_strdup_printf("%s/%s", prop->name, path);
976
                    g_free(path);
977
                    path = newpath;
978
                } else {
979
                    path = g_strdup(prop->name);
980
                }
981
                break;
982
            }
983
        }
984

    
985
        g_assert(prop != NULL);
986

    
987
        obj = obj->parent;
988
    }
989

    
990
    newpath = g_strdup_printf("/%s", path);
991
    g_free(path);
992

    
993
    return newpath;
994
}
995

    
996
static Object *object_resolve_abs_path(Object *parent,
997
                                          gchar **parts,
998
                                          const char *typename,
999
                                          int index)
1000
{
1001
    ObjectProperty *prop;
1002
    Object *child;
1003

    
1004
    if (parts[index] == NULL) {
1005
        return object_dynamic_cast(parent, typename);
1006
    }
1007

    
1008
    if (strcmp(parts[index], "") == 0) {
1009
        return object_resolve_abs_path(parent, parts, typename, index + 1);
1010
    }
1011

    
1012
    prop = object_property_find(parent, parts[index]);
1013
    if (prop == NULL) {
1014
        return NULL;
1015
    }
1016

    
1017
    child = NULL;
1018
    if (strstart(prop->type, "link<", NULL)) {
1019
        Object **pchild = prop->opaque;
1020
        if (*pchild) {
1021
            child = *pchild;
1022
        }
1023
    } else if (strstart(prop->type, "child<", NULL)) {
1024
        child = prop->opaque;
1025
    }
1026

    
1027
    if (!child) {
1028
        return NULL;
1029
    }
1030

    
1031
    return object_resolve_abs_path(child, parts, typename, index + 1);
1032
}
1033

    
1034
static Object *object_resolve_partial_path(Object *parent,
1035
                                              gchar **parts,
1036
                                              const char *typename,
1037
                                              bool *ambiguous)
1038
{
1039
    Object *obj;
1040
    ObjectProperty *prop;
1041

    
1042
    obj = object_resolve_abs_path(parent, parts, typename, 0);
1043

    
1044
    QTAILQ_FOREACH(prop, &parent->properties, node) {
1045
        Object *found;
1046

    
1047
        if (!strstart(prop->type, "child<", NULL)) {
1048
            continue;
1049
        }
1050

    
1051
        found = object_resolve_partial_path(prop->opaque, parts,
1052
                                            typename, ambiguous);
1053
        if (found) {
1054
            if (obj) {
1055
                if (ambiguous) {
1056
                    *ambiguous = true;
1057
                }
1058
                return NULL;
1059
            }
1060
            obj = found;
1061
        }
1062

    
1063
        if (ambiguous && *ambiguous) {
1064
            return NULL;
1065
        }
1066
    }
1067

    
1068
    return obj;
1069
}
1070

    
1071
Object *object_resolve_path_type(const char *path, const char *typename,
1072
                                 bool *ambiguous)
1073
{
1074
    bool partial_path = true;
1075
    Object *obj;
1076
    gchar **parts;
1077

    
1078
    parts = g_strsplit(path, "/", 0);
1079
    if (parts == NULL || parts[0] == NULL) {
1080
        g_strfreev(parts);
1081
        return object_get_root();
1082
    }
1083

    
1084
    if (strcmp(parts[0], "") == 0) {
1085
        partial_path = false;
1086
    }
1087

    
1088
    if (partial_path) {
1089
        if (ambiguous) {
1090
            *ambiguous = false;
1091
        }
1092
        obj = object_resolve_partial_path(object_get_root(), parts,
1093
                                          typename, ambiguous);
1094
    } else {
1095
        obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
1096
    }
1097

    
1098
    g_strfreev(parts);
1099

    
1100
    return obj;
1101
}
1102

    
1103
Object *object_resolve_path(const char *path, bool *ambiguous)
1104
{
1105
    return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
1106
}
1107

    
1108
typedef struct StringProperty
1109
{
1110
    char *(*get)(Object *, Error **);
1111
    void (*set)(Object *, const char *, Error **);
1112
} StringProperty;
1113

    
1114
static void property_get_str(Object *obj, Visitor *v, void *opaque,
1115
                             const char *name, Error **errp)
1116
{
1117
    StringProperty *prop = opaque;
1118
    char *value;
1119

    
1120
    value = prop->get(obj, errp);
1121
    if (value) {
1122
        visit_type_str(v, &value, name, errp);
1123
        g_free(value);
1124
    }
1125
}
1126

    
1127
static void property_set_str(Object *obj, Visitor *v, void *opaque,
1128
                             const char *name, Error **errp)
1129
{
1130
    StringProperty *prop = opaque;
1131
    char *value;
1132
    Error *local_err = NULL;
1133

    
1134
    visit_type_str(v, &value, name, &local_err);
1135
    if (local_err) {
1136
        error_propagate(errp, local_err);
1137
        return;
1138
    }
1139

    
1140
    prop->set(obj, value, errp);
1141
    g_free(value);
1142
}
1143

    
1144
static void property_release_str(Object *obj, const char *name,
1145
                                 void *opaque)
1146
{
1147
    StringProperty *prop = opaque;
1148
    g_free(prop);
1149
}
1150

    
1151
void object_property_add_str(Object *obj, const char *name,
1152
                           char *(*get)(Object *, Error **),
1153
                           void (*set)(Object *, const char *, Error **),
1154
                           Error **errp)
1155
{
1156
    StringProperty *prop = g_malloc0(sizeof(*prop));
1157

    
1158
    prop->get = get;
1159
    prop->set = set;
1160

    
1161
    object_property_add(obj, name, "string",
1162
                        get ? property_get_str : NULL,
1163
                        set ? property_set_str : NULL,
1164
                        property_release_str,
1165
                        prop, errp);
1166
}