object.c revision 1365eb2b35736211464f313616e32f25569e5107
1910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner/* 2910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * QEMU Object Model 3910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * 4910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * Copyright IBM, Corp. 2011 5910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * 6910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * Authors: 7910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * Anthony Liguori <aliguori@us.ibm.com> 8910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * 9910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * This work is licensed under the terms of the GNU GPL, version 2 or later. 10910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * See the COPYING file in the top-level directory. 11910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner */ 12910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 13910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qom/object.h" 14910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qemu-common.h" 15910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qapi/visitor.h" 16910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qapi/string-input-visitor.h" 17910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qapi/string-output-visitor.h" 18910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qapi/qmp/qerror.h" 19910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "trace.h" 20910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 21910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner/* TODO: replace QObject with a simpler visitor to avoid a dependency 22910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * of the QOM core on QObject? */ 23910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qom/qom-qobject.h" 24910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qapi/qmp/qobject.h" 25910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qapi/qmp/qbool.h" 26910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qapi/qmp/qint.h" 27910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qapi/qmp/qstring.h" 28910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 29910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#define MAX_INTERFACES 32 30910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 31910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertypedef struct InterfaceImpl InterfaceImpl; 32910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertypedef struct TypeImpl TypeImpl; 33910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 34910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstruct InterfaceImpl 35910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 36910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *typename; 37910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner}; 38910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 39910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstruct TypeImpl 40910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 41910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name; 42910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 43910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner size_t class_size; 44910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 45910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner size_t instance_size; 46910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 47910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void (*class_init)(ObjectClass *klass, void *data); 48910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void (*class_base_init)(ObjectClass *klass, void *data); 49910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void (*class_finalize)(ObjectClass *klass, void *data); 50910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 51910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *class_data; 52910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 53910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void (*instance_init)(Object *obj); 54910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void (*instance_post_init)(Object *obj); 55910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void (*instance_finalize)(Object *obj); 56910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 57910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner bool abstract; 58910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 59910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *parent; 60910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *parent_type; 61910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 62910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectClass *class; 63910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 64910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner int num_interfaces; 65910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner InterfaceImpl interfaces[MAX_INTERFACES]; 66910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner}; 67910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 68910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic Type type_interface; 69910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 70910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic GHashTable *type_table_get(void) 71910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 72910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner static GHashTable *type_table; 73910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 74910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type_table == NULL) { 75910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_table = g_hash_table_new(g_str_hash, g_str_equal); 76910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 77910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 78910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return type_table; 79910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 80910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 81910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void type_table_add(TypeImpl *ti) 82910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 83910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_hash_table_insert(type_table_get(), (void *)ti->name, ti); 84910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 85910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 86910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic TypeImpl *type_table_lookup(const char *name) 87910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 88910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return g_hash_table_lookup(type_table_get(), name); 89910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 90910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 91910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic TypeImpl *type_register_internal(const TypeInfo *info) 92910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 93910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *ti = g_malloc0(sizeof(*ti)); 94910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner int i; 95910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 96910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(info->name != NULL); 97910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 98910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type_table_lookup(info->name) != NULL) { 99910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner fprintf(stderr, "Registering `%s' which already exists\n", info->name); 100910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner abort(); 101910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 102910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 103910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->name = g_strdup(info->name); 104910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->parent = g_strdup(info->parent); 105910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 106910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->class_size = info->class_size; 107910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->instance_size = info->instance_size; 108910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 109910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->class_init = info->class_init; 110910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->class_base_init = info->class_base_init; 111910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->class_finalize = info->class_finalize; 112910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->class_data = info->class_data; 113910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 114910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->instance_init = info->instance_init; 115910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->instance_post_init = info->instance_post_init; 116910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->instance_finalize = info->instance_finalize; 117910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 118910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->abstract = info->abstract; 119910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 120910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner for (i = 0; info->interfaces && info->interfaces[i].type; i++) { 121910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->interfaces[i].typename = g_strdup(info->interfaces[i].type); 122910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 123910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->num_interfaces = i; 124910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 125910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_table_add(ti); 126910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 127910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return ti; 128910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 129910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 130910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerTypeImpl *type_register(const TypeInfo *info) 131910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 132910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner assert(info->parent); 133910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return type_register_internal(info); 134910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 135910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 136910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerTypeImpl *type_register_static(const TypeInfo *info) 137910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 138910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return type_register(info); 139910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 140910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 141910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic TypeImpl *type_get_by_name(const char *name) 142910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 143910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (name == NULL) { 144910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 145910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 146910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 147910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return type_table_lookup(name); 148910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 149910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 150910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic TypeImpl *type_get_parent(TypeImpl *type) 151910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 152910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!type->parent_type && type->parent) { 153910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type->parent_type = type_get_by_name(type->parent); 154910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(type->parent_type != NULL); 155910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 156910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 157910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return type->parent_type; 158910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 159910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 160910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic bool type_has_parent(TypeImpl *type) 161910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 162910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return (type->parent != NULL); 163910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 164910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 165910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic size_t type_class_get_size(TypeImpl *ti) 166910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 167910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (ti->class_size) { 168910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return ti->class_size; 169910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 170910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 171910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type_has_parent(ti)) { 172910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return type_class_get_size(type_get_parent(ti)); 173910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 174910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 175910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return sizeof(ObjectClass); 176910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 177910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 178910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic size_t type_object_get_size(TypeImpl *ti) 179910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 180910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (ti->instance_size) { 181910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return ti->instance_size; 182910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 183910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 184910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type_has_parent(ti)) { 185910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return type_object_get_size(type_get_parent(ti)); 186910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 187910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 188910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return 0; 189910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 190910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 191910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type) 192910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 193910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner assert(target_type); 194910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 195910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner /* Check if typename is a direct ancestor of type */ 196910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner while (type) { 197910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type == target_type) { 198910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return true; 199910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 200910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 201910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type = type_get_parent(type); 202910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 203910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 204910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return false; 205910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 206910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 207910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void type_initialize(TypeImpl *ti); 208910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 209910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void type_initialize_interface(TypeImpl *ti, const char *parent) 210910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 211910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner InterfaceClass *new_iface; 212910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeInfo info = { }; 213910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *iface_impl; 214910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 215910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner info.parent = parent; 216910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner info.name = g_strdup_printf("%s::%s", ti->name, info.parent); 217910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner info.abstract = true; 218910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 219910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner iface_impl = type_register(&info); 220910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_initialize(iface_impl); 221910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free((char *)info.name); 222910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 223910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner new_iface = (InterfaceClass *)iface_impl->class; 224910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner new_iface->concrete_class = ti->class; 225910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 226910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->class->interfaces = g_slist_append(ti->class->interfaces, 227910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner iface_impl->class); 228910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 229910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 230910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void type_initialize(TypeImpl *ti) 231910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 232910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *parent; 233910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 234910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (ti->class) { 235910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return; 236910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 237910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 238910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->class_size = type_class_get_size(ti); 239910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->instance_size = type_object_get_size(ti); 240910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 241910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->class = g_malloc0(ti->class_size); 242910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 243910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner parent = type_get_parent(ti); 244910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (parent) { 245910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_initialize(parent); 246910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner GSList *e; 247910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner int i; 248910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 249910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(parent->class_size <= ti->class_size); 250910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner memcpy(ti->class, parent->class, parent->class_size); 251910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->class->interfaces = NULL; 252910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 253910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner for (e = parent->class->interfaces; e; e = e->next) { 254910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectClass *iface = e->data; 255910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_initialize_interface(ti, object_class_get_name(iface)); 256910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 257910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 258910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner for (i = 0; i < ti->num_interfaces; i++) { 259910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *t = type_get_by_name(ti->interfaces[i].typename); 260910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner for (e = ti->class->interfaces; e; e = e->next) { 261910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *target_type = OBJECT_CLASS(e->data)->type; 262910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 263910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type_is_ancestor(target_type, t)) { 264910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner break; 265910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 266910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 267910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 268910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (e) { 269910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner continue; 270910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 271910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 272910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_initialize_interface(ti, ti->interfaces[i].typename); 273910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 274910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 275910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 276910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->class->type = ti; 277910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 278910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner while (parent) { 279910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (parent->class_base_init) { 280910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner parent->class_base_init(ti->class, ti->class_data); 281910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 282910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner parent = type_get_parent(parent); 283910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 284910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 285910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (ti->class_init) { 286910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->class_init(ti->class, ti->class_data); 287910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 288910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 289910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 290910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 291910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 292910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_init_with_type(Object *obj, TypeImpl *ti) 293910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 294910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type_has_parent(ti)) { 295910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_init_with_type(obj, type_get_parent(ti)); 296910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 297910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 298910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (ti->instance_init) { 299910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->instance_init(obj); 300910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 301910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 302910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 303910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_post_init_with_type(Object *obj, TypeImpl *ti) 304910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 305910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (ti->instance_post_init) { 306910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ti->instance_post_init(obj); 307910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 308910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 309910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type_has_parent(ti)) { 310910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_post_init_with_type(obj, type_get_parent(ti)); 311910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 312910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 313910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 314910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_initialize_with_type(void *data, size_t size, TypeImpl *type) 315910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 316910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *obj = data; 317910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 318910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(type != NULL); 319910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_initialize(type); 320910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 321910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(type->instance_size >= sizeof(Object)); 322910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(type->abstract == false); 323910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(size >= type->instance_size); 324910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 325910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner memset(obj, 0, type->instance_size); 326910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner obj->class = type->class; 327910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_ref(obj); 328910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QTAILQ_INIT(&obj->properties); 329910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_init_with_type(obj, type); 330910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_post_init_with_type(obj, type); 331910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 332910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 333910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_initialize(void *data, size_t size, const char *typename) 334910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 335910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *type = type_get_by_name(typename); 336910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 337910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_initialize_with_type(data, size, type); 338910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 339910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 340910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic inline bool object_property_is_child(ObjectProperty *prop) 341910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 342910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return strstart(prop->type, "child<", NULL); 343910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 344910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 345910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic inline bool object_property_is_link(ObjectProperty *prop) 346910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 347910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return strstart(prop->type, "link<", NULL); 348910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 349910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 350910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_property_del_all(Object *obj) 351910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 352910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner while (!QTAILQ_EMPTY(&obj->properties)) { 353910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop = QTAILQ_FIRST(&obj->properties); 354910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 355910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QTAILQ_REMOVE(&obj->properties, prop, node); 356910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 357910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (prop->release) { 358910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->release(obj, prop->name, prop->opaque); 359910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 360910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 361910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(prop->name); 362910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(prop->type); 363910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(prop); 364910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 365910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 366910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 367910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_property_del_child(Object *obj, Object *child, Error **errp) 368910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 369910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop; 370910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 371910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QTAILQ_FOREACH(prop, &obj->properties, node) { 372910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (object_property_is_child(prop) && prop->opaque == child) { 373910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_del(obj, prop->name, errp); 374910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner break; 375910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 376910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 377910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 378910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 379910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_unparent(Object *obj) 380910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 381910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!obj->parent) { 382910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return; 383910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 384910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 385910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_ref(obj); 386910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (obj->class->unparent) { 387910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner (obj->class->unparent)(obj); 388910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 389910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (obj->parent) { 390910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_del_child(obj->parent, obj, NULL); 391910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 392910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_unref(obj); 393910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 394910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 395910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_deinit(Object *obj, TypeImpl *type) 396910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 397910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type->instance_finalize) { 398910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type->instance_finalize(obj); 399910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 400910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 401910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type_has_parent(type)) { 402910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_deinit(obj, type_get_parent(type)); 403910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 404910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 405910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 406910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_finalize(void *data) 407910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 408910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *obj = data; 409910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *ti = obj->class->type; 410910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 411910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_deinit(obj, ti); 412910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_del_all(obj); 413910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 414910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(obj->ref == 0); 415910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (obj->free) { 416910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner obj->free(obj); 417910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 418910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 419910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 420910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObject *object_new_with_type(Type type) 421910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 422910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *obj; 423910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 424910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(type != NULL); 425910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_initialize(type); 426910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 427910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner obj = g_malloc(type->instance_size); 428910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_initialize_with_type(obj, type->instance_size, type); 429910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner obj->free = g_free; 430910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 431910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return obj; 432910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 433910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 434910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObject *object_new(const char *typename) 435910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 436910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *ti = type_get_by_name(typename); 437910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 438910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return object_new_with_type(ti); 439910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 440910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 441910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObject *object_dynamic_cast(Object *obj, const char *typename) 442910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 443910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) { 444910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return obj; 445910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 446910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 447910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 448910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 449910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 450910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObject *object_dynamic_cast_assert(Object *obj, const char *typename, 451910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *file, int line, const char *func) 452910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 4531365eb2b35736211464f313616e32f25569e5107David 'Digit' Turner //trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)", 4541365eb2b35736211464f313616e32f25569e5107David 'Digit' Turner // typename, file, line, func); 455910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 456910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#ifdef CONFIG_QOM_CAST_DEBUG 457910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner int i; 458910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *inst; 459910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 460910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) { 461910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (obj->class->cast_cache[i] == typename) { 462910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner goto out; 463910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 464910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 465910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 466910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner inst = object_dynamic_cast(obj, typename); 467910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 468910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!inst && obj) { 469910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", 470910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner file, line, func, obj, typename); 471910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner abort(); 472910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 473910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 474910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner assert(obj == inst); 475910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 476910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (obj && obj == inst) { 477910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { 478910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner obj->class->cast_cache[i - 1] = obj->class->cast_cache[i]; 479910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 480910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner obj->class->cast_cache[i - 1] = typename; 481910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 482910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 483910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerout: 484910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#endif 485910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return obj; 486910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 487910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 488910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObjectClass *object_class_dynamic_cast(ObjectClass *class, 489910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *typename) 490910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 491910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectClass *ret = NULL; 492910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *target_type; 493910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *type; 494910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 495910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!class) { 496910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 497910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 498910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 499910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner /* A simple fast path that can trigger a lot for leaf classes. */ 500910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type = class->type; 501910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type->name == typename) { 502910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return class; 503910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 504910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 505910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner target_type = type_get_by_name(typename); 506910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!target_type) { 507910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner /* target class type unknown, so fail the cast */ 508910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 509910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 510910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 511910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type->class->interfaces && 512910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_is_ancestor(target_type, type_interface)) { 513910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner int found = 0; 514910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner GSList *i; 515910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 516910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner for (i = class->interfaces; i; i = i->next) { 517910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectClass *target_class = i->data; 518910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 519910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (type_is_ancestor(target_class->type, target_type)) { 520910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ret = target_class; 521910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner found++; 522910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 523910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 524910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 525910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner /* The match was ambiguous, don't allow a cast */ 526910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (found > 1) { 527910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ret = NULL; 528910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 529910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else if (type_is_ancestor(type, target_type)) { 530910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ret = class; 531910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 532910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 533910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return ret; 534910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 535910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 536910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, 537910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *typename, 538910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *file, int line, 539910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *func) 540910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 541910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectClass *ret; 542910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 5431365eb2b35736211464f313616e32f25569e5107David 'Digit' Turner //trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)", 5441365eb2b35736211464f313616e32f25569e5107David 'Digit' Turner // typename, file, line, func); 545910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 546910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#ifdef CONFIG_QOM_CAST_DEBUG 547910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner int i; 548910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 549910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) { 550910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (class->cast_cache[i] == typename) { 551910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ret = class; 552910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner goto out; 553910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 554910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 555910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#else 556910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!class || !class->interfaces) { 557910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return class; 558910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 559910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#endif 560910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 561910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ret = object_class_dynamic_cast(class, typename); 562910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!ret && class) { 563910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", 564910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner file, line, func, class, typename); 565910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner abort(); 566910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 567910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 568910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#ifdef CONFIG_QOM_CAST_DEBUG 569910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (class && ret == class) { 570910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { 571910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner class->cast_cache[i - 1] = class->cast_cache[i]; 572910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 573910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner class->cast_cache[i - 1] = typename; 574910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 575910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerout: 576910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#endif 577910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return ret; 578910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 579910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 580910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerconst char *object_get_typename(Object *obj) 581910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 582910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return obj->class->type->name; 583910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 584910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 585910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObjectClass *object_get_class(Object *obj) 586910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 587910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return obj->class; 588910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 589910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 590910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerbool object_class_is_abstract(ObjectClass *klass) 591910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 592910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return klass->type->abstract; 593910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 594910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 595910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerconst char *object_class_get_name(ObjectClass *klass) 596910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 597910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return klass->type->name; 598910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 599910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 600910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObjectClass *object_class_by_name(const char *typename) 601910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 602910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *type = type_get_by_name(typename); 603910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 604910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!type) { 605910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 606910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 607910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 608910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_initialize(type); 609910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 610910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return type->class; 611910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 612910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 613910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObjectClass *object_class_get_parent(ObjectClass *class) 614910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 615910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *type = type_get_parent(class->type); 616910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 617910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!type) { 618910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 619910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 620910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 621910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_initialize(type); 622910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 623910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return type->class; 624910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 625910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 626910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertypedef struct OCFData 627910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 628910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void (*fn)(ObjectClass *klass, void *opaque); 629910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *implements_type; 630910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner bool include_abstract; 631910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *opaque; 632910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} OCFData; 633910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 634910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_class_foreach_tramp(gpointer key, gpointer value, 635910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner gpointer opaque) 636910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 637910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner OCFData *data = opaque; 638910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner TypeImpl *type = value; 639910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectClass *k; 640910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 641910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_initialize(type); 642910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner k = type->class; 643910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 644910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!data->include_abstract && type->abstract) { 645910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return; 646910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 647910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 648910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (data->implements_type && 649910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner !object_class_dynamic_cast(k, data->implements_type)) { 650910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return; 651910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 652910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 653910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner data->fn(k, data->opaque); 654910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 655910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 656910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), 657910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *implements_type, bool include_abstract, 658910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *opaque) 659910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 660910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner OCFData data = { fn, implements_type, include_abstract, opaque }; 661910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 662910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data); 663910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 664910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 665910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerint object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), 666910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *opaque) 667910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 668910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop; 669910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner int ret = 0; 670910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 671910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QTAILQ_FOREACH(prop, &obj->properties, node) { 672910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (object_property_is_child(prop)) { 673910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ret = fn(prop->opaque, opaque); 674910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (ret != 0) { 675910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner break; 676910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 677910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 678910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 679910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return ret; 680910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 681910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 682910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_class_get_list_tramp(ObjectClass *klass, void *opaque) 683910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 684910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner GSList **list = opaque; 685910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 686910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *list = g_slist_prepend(*list, klass); 687910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 688910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 689910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerGSList *object_class_get_list(const char *implements_type, 690910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner bool include_abstract) 691910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 692910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner GSList *list = NULL; 693910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 694910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_class_foreach(object_class_get_list_tramp, 695910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner implements_type, include_abstract, &list); 696910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return list; 697910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 698910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 699910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_ref(Object *obj) 700910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 701910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner atomic_inc(&obj->ref); 702910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 703910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 704910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_unref(Object *obj) 705910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 706910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(obj->ref > 0); 707910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 708910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner /* parent always holds a reference to its children */ 709910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (atomic_fetch_dec(&obj->ref) == 1) { 710910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_finalize(obj); 711910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 712910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 713910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 714910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_add(Object *obj, const char *name, const char *type, 715910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectPropertyAccessor *get, 716910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectPropertyAccessor *set, 717910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectPropertyRelease *release, 718910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *opaque, Error **errp) 719910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 720910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop; 721910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 722910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QTAILQ_FOREACH(prop, &obj->properties, node) { 723910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (strcmp(prop->name, name) == 0) { 724910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_setg(errp, "attempt to add duplicate property '%s'" 725910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner " to object (type '%s')", name, 726910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_get_typename(obj)); 727910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return; 728910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 729910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 730910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 731910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop = g_malloc0(sizeof(*prop)); 732910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 733910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->name = g_strdup(name); 734910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->type = g_strdup(type); 735910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 736910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->get = get; 737910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->set = set; 738910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->release = release; 739910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->opaque = opaque; 740910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 741910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QTAILQ_INSERT_TAIL(&obj->properties, prop, node); 742910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 743910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 744910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObjectProperty *object_property_find(Object *obj, const char *name, 745910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 746910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 747910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop; 748910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 749910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QTAILQ_FOREACH(prop, &obj->properties, node) { 750910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (strcmp(prop->name, name) == 0) { 751910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return prop; 752910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 753910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 754910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 755910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name); 756910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 757910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 758910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 759910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_del(Object *obj, const char *name, Error **errp) 760910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 761910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop = object_property_find(obj, name, errp); 762910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (prop == NULL) { 763910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return; 764910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 765910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 766910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (prop->release) { 767910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->release(obj, name, prop->opaque); 768910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 769910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 770910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QTAILQ_REMOVE(&obj->properties, prop, node); 771910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 772910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(prop->name); 773910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(prop->type); 774910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(prop); 775910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 776910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 777910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_get(Object *obj, Visitor *v, const char *name, 778910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 779910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 780910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop = object_property_find(obj, name, errp); 781910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (prop == NULL) { 782910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return; 783910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 784910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 785910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!prop->get) { 786910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_set(errp, QERR_PERMISSION_DENIED); 787910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else { 788910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->get(obj, v, prop->opaque, name, errp); 789910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 790910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 791910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 792910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_set(Object *obj, Visitor *v, const char *name, 793910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 794910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 795910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop = object_property_find(obj, name, errp); 796910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (prop == NULL) { 797910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return; 798910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 799910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 800910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!prop->set) { 801910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_set(errp, QERR_PERMISSION_DENIED); 802910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else { 803910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->set(obj, v, prop->opaque, name, errp); 804910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 805910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 806910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 807910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_set_str(Object *obj, const char *value, 808910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 809910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 810910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QString *qstr = qstring_from_str(value); 811910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_set_qobject(obj, QOBJECT(qstr), name, errp); 812910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 813910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QDECREF(qstr); 814910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 815910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 816910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerchar *object_property_get_str(Object *obj, const char *name, 817910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 818910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 819910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QObject *ret = object_property_get_qobject(obj, name, errp); 820910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QString *qstring; 821910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner char *retval; 822910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 823910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!ret) { 824910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 825910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 826910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner qstring = qobject_to_qstring(ret); 827910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!qstring) { 828910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "string"); 829910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner retval = NULL; 830910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else { 831910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner retval = g_strdup(qstring_get_str(qstring)); 832910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 833910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 834910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QDECREF(qstring); 835910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return retval; 836910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 837910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 838910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_set_link(Object *obj, Object *value, 839910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 840910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 841910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner gchar *path = object_get_canonical_path(value); 842910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_set_str(obj, path, name, errp); 843910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(path); 844910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 845910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 846910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObject *object_property_get_link(Object *obj, const char *name, 847910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 848910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 849910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner char *str = object_property_get_str(obj, name, errp); 850910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *target = NULL; 851910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 852910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (str && *str) { 853910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner target = object_resolve_path(str, NULL); 854910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!target) { 855910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_set(errp, QERR_DEVICE_NOT_FOUND, str); 856910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 857910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 858910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 859910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(str); 860910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return target; 861910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 862910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 863910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_set_bool(Object *obj, bool value, 864910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 865910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 866910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QBool *qbool = qbool_from_int(value); 867910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_set_qobject(obj, QOBJECT(qbool), name, errp); 868910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 869910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QDECREF(qbool); 870910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 871910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 872910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerbool object_property_get_bool(Object *obj, const char *name, 873910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 874910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 875910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QObject *ret = object_property_get_qobject(obj, name, errp); 876910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QBool *qbool; 877910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner bool retval; 878910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 879910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!ret) { 880910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return false; 881910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 882910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner qbool = qobject_to_qbool(ret); 883910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!qbool) { 884910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean"); 885910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner retval = false; 886910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else { 887910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner retval = qbool_get_int(qbool); 888910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 889910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 890910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QDECREF(qbool); 891910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return retval; 892910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 893910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 894910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_set_int(Object *obj, int64_t value, 895910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 896910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 897910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QInt *qint = qint_from_int(value); 898910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_set_qobject(obj, QOBJECT(qint), name, errp); 899910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 900910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QDECREF(qint); 901910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 902910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 903910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerint64_t object_property_get_int(Object *obj, const char *name, 904910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 905910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 906910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QObject *ret = object_property_get_qobject(obj, name, errp); 907910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QInt *qint; 908910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner int64_t retval; 909910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 910910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!ret) { 911910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return -1; 912910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 913910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner qint = qobject_to_qint(ret); 914910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!qint) { 915910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int"); 916910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner retval = -1; 917910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else { 918910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner retval = qint_get_int(qint); 919910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 920910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 921910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QDECREF(qint); 922910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return retval; 923910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 924910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 925910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_parse(Object *obj, const char *string, 926910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 927910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 928910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner StringInputVisitor *mi; 929910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner mi = string_input_visitor_new(string); 930910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_set(obj, string_input_get_visitor(mi), name, errp); 931910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 932910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner string_input_visitor_cleanup(mi); 933910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 934910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 935910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerchar *object_property_print(Object *obj, const char *name, 936910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 937910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 938910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner StringOutputVisitor *mo; 939910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner char *string; 940910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 941910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner mo = string_output_visitor_new(); 942910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_get(obj, string_output_get_visitor(mo), name, errp); 943910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner string = string_output_get_string(mo); 944910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner string_output_visitor_cleanup(mo); 945910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return string; 946910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 947910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 948910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerconst char *object_property_get_type(Object *obj, const char *name, Error **errp) 949910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 950910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop = object_property_find(obj, name, errp); 951910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (prop == NULL) { 952910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 953910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 954910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 955910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return prop->type; 956910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 957910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 958910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObject *object_get_root(void) 959910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 960910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner static Object *root; 961910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 962910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!root) { 963910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner root = object_new("container"); 964910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 965910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 966910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return root; 967910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 968910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 969910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_get_child_property(Object *obj, Visitor *v, void *opaque, 970910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 971910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 972910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *child = opaque; 973910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner gchar *path; 974910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 975910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner path = object_get_canonical_path(child); 976910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_str(v, &path, name, errp); 977910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(path); 978910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 979910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 980910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_finalize_child_property(Object *obj, const char *name, 981910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *opaque) 982910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 983910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *child = opaque; 984910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 985910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_unref(child); 986910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 987910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 988910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_add_child(Object *obj, const char *name, 989910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *child, Error **errp) 990910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 991910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner gchar *type; 992910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 993910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child))); 994910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 995910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_add(obj, name, type, object_get_child_property, 996910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner NULL, object_finalize_child_property, child, errp); 997910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 998910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_ref(child); 999910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(child->parent == NULL); 1000910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner child->parent = obj; 1001910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1002910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(type); 1003910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1004910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1005910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_get_link_property(Object *obj, Visitor *v, void *opaque, 1006910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 1007910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1008910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object **child = opaque; 1009910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner gchar *path; 1010910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1011910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (*child) { 1012910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner path = object_get_canonical_path(*child); 1013910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_str(v, &path, name, errp); 1014910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(path); 1015910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else { 1016910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner path = (gchar *)""; 1017910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_str(v, &path, name, errp); 1018910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1019910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1020910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1021910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_set_link_property(Object *obj, Visitor *v, void *opaque, 1022910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 1023910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1024910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object **child = opaque; 1025910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *old_target; 1026910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner bool ambiguous = false; 1027910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *type; 1028910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner char *path; 1029910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner gchar *target_type; 1030910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1031910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type = object_property_get_type(obj, name, NULL); 1032910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1033910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_str(v, &path, name, errp); 1034910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1035910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner old_target = *child; 1036910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *child = NULL; 1037910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1038910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (strcmp(path, "") != 0) { 1039910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *target; 1040910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1041910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner /* Go from link<FOO> to FOO. */ 1042910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner target_type = g_strndup(&type[5], strlen(type) - 6); 1043910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner target = object_resolve_path_type(path, target_type, &ambiguous); 1044910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1045910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (ambiguous) { 1046910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_set(errp, QERR_AMBIGUOUS_PATH, path); 1047910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else if (target) { 1048910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_ref(target); 1049910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *child = target; 1050910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else { 1051910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner target = object_resolve_path(path, &ambiguous); 1052910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (target || ambiguous) { 1053910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type); 1054910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else { 1055910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_set(errp, QERR_DEVICE_NOT_FOUND, path); 1056910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1057910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1058910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(target_type); 1059910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1060910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1061910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(path); 1062910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1063910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (old_target != NULL) { 1064910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_unref(old_target); 1065910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1066910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1067910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1068910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_add_link(Object *obj, const char *name, 1069910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *type, Object **child, 1070910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 1071910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1072910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner gchar *full_type; 1073910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1074910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner full_type = g_strdup_printf("link<%s>", type); 1075910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1076910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_add(obj, name, full_type, 1077910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_get_link_property, 1078910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_set_link_property, 1079910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner NULL, child, errp); 1080910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1081910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(full_type); 1082910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1083910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1084910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnergchar *object_get_canonical_path(Object *obj) 1085910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1086910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *root = object_get_root(); 1087910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner char *newpath = NULL, *path = NULL; 1088910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1089910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner while (obj != root) { 1090910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop = NULL; 1091910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1092910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(obj->parent != NULL); 1093910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1094910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QTAILQ_FOREACH(prop, &obj->parent->properties, node) { 1095910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!object_property_is_child(prop)) { 1096910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner continue; 1097910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1098910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1099910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (prop->opaque == obj) { 1100910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (path) { 1101910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner newpath = g_strdup_printf("%s/%s", prop->name, path); 1102910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(path); 1103910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner path = newpath; 1104910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else { 1105910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner path = g_strdup(prop->name); 1106910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1107910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner break; 1108910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1109910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1110910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1111910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_assert(prop != NULL); 1112910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1113910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner obj = obj->parent; 1114910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1115910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1116910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner newpath = g_strdup_printf("/%s", path); 1117910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(path); 1118910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1119910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return newpath; 1120910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1121910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1122910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObject *object_resolve_path_component(Object *parent, const gchar *part) 1123910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1124910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop = object_property_find(parent, part, NULL); 1125910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (prop == NULL) { 1126910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 1127910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1128910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1129910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (object_property_is_link(prop)) { 1130910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return *(Object **)prop->opaque; 1131910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else if (object_property_is_child(prop)) { 1132910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return prop->opaque; 1133910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else { 1134910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 1135910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1136910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1137910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1138910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic Object *object_resolve_abs_path(Object *parent, 1139910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner gchar **parts, 1140910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *typename, 1141910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner int index) 1142910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1143910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *child; 1144910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1145910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (parts[index] == NULL) { 1146910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return object_dynamic_cast(parent, typename); 1147910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1148910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1149910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (strcmp(parts[index], "") == 0) { 1150910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return object_resolve_abs_path(parent, parts, typename, index + 1); 1151910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1152910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1153910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner child = object_resolve_path_component(parent, parts[index]); 1154910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!child) { 1155910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 1156910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1157910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1158910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return object_resolve_abs_path(child, parts, typename, index + 1); 1159910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1160910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1161910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic Object *object_resolve_partial_path(Object *parent, 1162910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner gchar **parts, 1163910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *typename, 1164910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner bool *ambiguous) 1165910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1166910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *obj; 1167910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner ObjectProperty *prop; 1168910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1169910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner obj = object_resolve_abs_path(parent, parts, typename, 0); 1170910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1171910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner QTAILQ_FOREACH(prop, &parent->properties, node) { 1172910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *found; 1173910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1174910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (!object_property_is_child(prop)) { 1175910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner continue; 1176910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1177910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1178910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner found = object_resolve_partial_path(prop->opaque, parts, 1179910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner typename, ambiguous); 1180910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (found) { 1181910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (obj) { 1182910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (ambiguous) { 1183910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *ambiguous = true; 1184910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1185910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 1186910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1187910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner obj = found; 1188910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1189910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1190910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (ambiguous && *ambiguous) { 1191910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return NULL; 1192910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1193910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1194910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1195910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return obj; 1196910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1197910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1198910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObject *object_resolve_path_type(const char *path, const char *typename, 1199910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner bool *ambiguous) 1200910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1201910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Object *obj; 1202910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner gchar **parts; 1203910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1204910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner parts = g_strsplit(path, "/", 0); 1205910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner assert(parts); 1206910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1207910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (parts[0] == NULL || strcmp(parts[0], "") != 0) { 1208910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (ambiguous) { 1209910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *ambiguous = false; 1210910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1211910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner obj = object_resolve_partial_path(object_get_root(), parts, 1212910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner typename, ambiguous); 1213910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } else { 1214910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner obj = object_resolve_abs_path(object_get_root(), parts, typename, 1); 1215910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1216910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1217910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_strfreev(parts); 1218910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1219910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return obj; 1220910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1221910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1222910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerObject *object_resolve_path(const char *path, bool *ambiguous) 1223910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1224910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return object_resolve_path_type(path, TYPE_OBJECT, ambiguous); 1225910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1226910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1227910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertypedef struct StringProperty 1228910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1229910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner char *(*get)(Object *, Error **); 1230910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void (*set)(Object *, const char *, Error **); 1231910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} StringProperty; 1232910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1233910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void property_get_str(Object *obj, Visitor *v, void *opaque, 1234910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 1235910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1236910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner StringProperty *prop = opaque; 1237910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner char *value; 1238910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1239910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner value = prop->get(obj, errp); 1240910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (value) { 1241910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_str(v, &value, name, errp); 1242910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(value); 1243910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1244910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1245910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1246910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void property_set_str(Object *obj, Visitor *v, void *opaque, 1247910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 1248910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1249910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner StringProperty *prop = opaque; 1250910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner char *value; 1251910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error *local_err = NULL; 1252910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1253910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_str(v, &value, name, &local_err); 1254910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (local_err) { 1255910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_propagate(errp, local_err); 1256910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return; 1257910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1258910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1259910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->set(obj, value, errp); 1260910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(value); 1261910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1262910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1263910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void property_release_str(Object *obj, const char *name, 1264910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *opaque) 1265910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1266910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner StringProperty *prop = opaque; 1267910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(prop); 1268910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1269910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1270910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_add_str(Object *obj, const char *name, 1271910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner char *(*get)(Object *, Error **), 1272910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void (*set)(Object *, const char *, Error **), 1273910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 1274910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1275910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner StringProperty *prop = g_malloc0(sizeof(*prop)); 1276910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1277910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->get = get; 1278910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->set = set; 1279910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1280910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_add(obj, name, "string", 1281910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner get ? property_get_str : NULL, 1282910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner set ? property_set_str : NULL, 1283910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner property_release_str, 1284910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop, errp); 1285910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1286910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1287910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertypedef struct BoolProperty 1288910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1289910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner bool (*get)(Object *, Error **); 1290910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void (*set)(Object *, bool, Error **); 1291910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} BoolProperty; 1292910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1293910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void property_get_bool(Object *obj, Visitor *v, void *opaque, 1294910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 1295910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1296910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner BoolProperty *prop = opaque; 1297910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner bool value; 1298910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1299910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner value = prop->get(obj, errp); 1300910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_bool(v, &value, name, errp); 1301910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1302910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1303910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void property_set_bool(Object *obj, Visitor *v, void *opaque, 1304910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const char *name, Error **errp) 1305910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1306910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner BoolProperty *prop = opaque; 1307910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner bool value; 1308910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error *local_err = NULL; 1309910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1310910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_bool(v, &value, name, &local_err); 1311910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner if (local_err) { 1312910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner error_propagate(errp, local_err); 1313910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return; 1314910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner } 1315910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1316910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->set(obj, value, errp); 1317910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1318910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1319910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void property_release_bool(Object *obj, const char *name, 1320910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *opaque) 1321910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1322910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner BoolProperty *prop = opaque; 1323910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner g_free(prop); 1324910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1325910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1326910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_add_bool(Object *obj, const char *name, 1327910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner bool (*get)(Object *, Error **), 1328910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void (*set)(Object *, bool, Error **), 1329910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 1330910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1331910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner BoolProperty *prop = g_malloc0(sizeof(*prop)); 1332910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1333910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->get = get; 1334910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop->set = set; 1335910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1336910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_add(obj, name, "bool", 1337910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner get ? property_get_bool : NULL, 1338910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner set ? property_set_bool : NULL, 1339910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner property_release_bool, 1340910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner prop, errp); 1341910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1342910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1343910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic char *qdev_get_type(Object *obj, Error **errp) 1344910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1345910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner return g_strdup(object_get_typename(obj)); 1346910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1347910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1348910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void property_get_uint8_ptr(Object *obj, Visitor *v, 1349910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *opaque, const char *name, 1350910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 1351910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1352910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner uint8_t value = *(uint8_t *)opaque; 1353910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_uint8(v, &value, name, errp); 1354910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1355910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1356910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void property_get_uint16_ptr(Object *obj, Visitor *v, 1357910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *opaque, const char *name, 1358910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 1359910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1360910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner uint16_t value = *(uint16_t *)opaque; 1361910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_uint16(v, &value, name, errp); 1362910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1363910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1364910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void property_get_uint32_ptr(Object *obj, Visitor *v, 1365910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *opaque, const char *name, 1366910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 1367910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1368910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner uint32_t value = *(uint32_t *)opaque; 1369910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_uint32(v, &value, name, errp); 1370910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1371910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1372910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void property_get_uint64_ptr(Object *obj, Visitor *v, 1373910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner void *opaque, const char *name, 1374910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner Error **errp) 1375910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1376910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner uint64_t value = *(uint64_t *)opaque; 1377910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner visit_type_uint64(v, &value, name, errp); 1378910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1379910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1380910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_add_uint8_ptr(Object *obj, const char *name, 1381910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const uint8_t *v, Error **errp) 1382910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1383910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_add(obj, name, "uint8", property_get_uint8_ptr, 1384910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner NULL, NULL, (void *)v, errp); 1385910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1386910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1387910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_add_uint16_ptr(Object *obj, const char *name, 1388910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const uint16_t *v, Error **errp) 1389910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1390910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_add(obj, name, "uint16", property_get_uint16_ptr, 1391910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner NULL, NULL, (void *)v, errp); 1392910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1393910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1394910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_add_uint32_ptr(Object *obj, const char *name, 1395910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const uint32_t *v, Error **errp) 1396910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1397910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_add(obj, name, "uint32", property_get_uint32_ptr, 1398910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner NULL, NULL, (void *)v, errp); 1399910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1400910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1401910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid object_property_add_uint64_ptr(Object *obj, const char *name, 1402910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner const uint64_t *v, Error **errp) 1403910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1404910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_add(obj, name, "uint64", property_get_uint64_ptr, 1405910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner NULL, NULL, (void *)v, errp); 1406910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1407910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1408910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void object_instance_init(Object *obj) 1409910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1410910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner object_property_add_str(obj, "type", qdev_get_type, NULL, NULL); 1411910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1412910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1413910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void register_types(void) 1414910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{ 1415910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner static TypeInfo interface_info = { 1416910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner .name = TYPE_INTERFACE, 1417910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner .class_size = sizeof(InterfaceClass), 1418910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner .abstract = true, 1419910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner }; 1420910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1421910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner static TypeInfo object_info = { 1422910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner .name = TYPE_OBJECT, 1423910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner .instance_size = sizeof(Object), 1424910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner .instance_init = object_instance_init, 1425910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner .abstract = true, 1426910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner }; 1427910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1428910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_interface = type_register_internal(&interface_info); 1429910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner type_register_internal(&object_info); 1430910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} 1431910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner 1432910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertype_init(register_types) 1433