diff options
author | Ewan Mellor <ewan@xensource.com> | 2007-02-01 19:02:13 +0000 |
---|---|---|
committer | Ewan Mellor <ewan@xensource.com> | 2007-02-01 19:02:13 +0000 |
commit | 948fd9f5a1e8db844b1a1f0a0fec93f5a29434cc (patch) | |
tree | 3d430a367897aac5cdbf2cfe96ce9b45b4e2116b /tools | |
parent | f72dfefae2eeaa789f23cc77787f5d18d253837b (diff) | |
download | xen-948fd9f5a1e8db844b1a1f0a0fec93f5a29434cc.tar.gz xen-948fd9f5a1e8db844b1a1f0a0fec93f5a29434cc.tar.bz2 xen-948fd9f5a1e8db844b1a1f0a0fec93f5a29434cc.zip |
Added support for maps inside structs, so that we can send the HVM boot params
and VCPU params.
Signed-off-by: Ewan Mellor <ewan@xensource.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/libxen/src/xen_common.c | 144 |
1 files changed, 106 insertions, 38 deletions
diff --git a/tools/libxen/src/xen_common.c b/tools/libxen/src/xen_common.c index 9834565ff0..8c5feeb33f 100644 --- a/tools/libxen/src/xen_common.c +++ b/tools/libxen/src/xen_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 XenSource, Inc. + * Copyright (c) 2006-2007 XenSource, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -86,6 +86,8 @@ static xmlNode * add_param_struct(xmlNode *); static xmlNode * add_struct_array(xmlNode *, const char *); +static xmlNode * +add_nested_struct(xmlNode *, const char *); static void add_struct_member(xmlNode *, const char *, const char *, const char *); static void @@ -107,6 +109,9 @@ parse_structmap_value(xen_session *, xmlNode *, const abstract_type *, static size_t size_of_member(const abstract_type *); +static const char * +get_val_as_string(const struct abstract_type *, void *, char *); + void xen_init(void) @@ -1174,37 +1179,12 @@ add_struct_value(const struct abstract_type *type, void *value, switch (type->typename) { case REF: - { - arbitrary_record_opt *val = *(arbitrary_record_opt **)value; - if (val != NULL) - { - if (val->is_record) - { - adder(node, key, "string", val->u.record->handle); - } - else - { - adder(node, key, "string", val->u.handle); - } - } - } - break; - case STRING: - { - char *val = *(char **)value; - if (val != NULL) - { - adder(node, key, "string", val); - } - } - break; - case INT: + case ENUM: { - int64_t val = *(int64_t *)value; - snprintf(buf, sizeof(buf), "%"PRId64, val); - adder(node, key, "string", buf); + const char *val_as_string = get_val_as_string(type, value, buf); + adder(node, key, "string", val_as_string); } break; @@ -1223,13 +1203,6 @@ add_struct_value(const struct abstract_type *type, void *value, } break; - case ENUM: - { - int val = *(int *)value; - adder(node, key, "string", type->enum_marshaller(val)); - } - break; - case SET: { const struct abstract_type *member_type = type->child; @@ -1251,12 +1224,95 @@ add_struct_value(const struct abstract_type *type, void *value, break; case STRUCT: - case MAP: { + assert(false); /* XXX Nested structures aren't supported yet, but fortunately we don't need them, because we don't have any "deep create" calls. This will need to be - fixed. We don't need maps either. */ + fixed. */ + } + break; + + case MAP: + { + size_t member_size = type->struct_size; + const struct abstract_type *l_type = type->members[0].type; + const struct abstract_type *r_type = type->members[1].type; + int l_offset = type->members[0].offset; + int r_offset = type->members[1].offset; + + arbitrary_map *map_val = *(arbitrary_map **)value; + + if (map_val != NULL) + { + xmlNode *struct_node = add_nested_struct(node, key); + + for (size_t i = 0; i < map_val->size; i++) + { + void *contents = (void *)map_val->contents; + void *l_value = contents + (i * member_size) + l_offset; + void *r_value = contents + (i * member_size) + r_offset; + + const char *l_value_as_string = + get_val_as_string(l_type, l_value, buf); + + add_struct_value(r_type, r_value, add_struct_member, + l_value_as_string, struct_node); + } + } + } + break; + + default: + assert(false); + } +} + + +static const char * +get_val_as_string(const struct abstract_type *type, void *value, char *buf) +{ + switch (type->typename) + { + case REF: + { + arbitrary_record_opt *val = *(arbitrary_record_opt **)value; + if (val != NULL) + { + if (val->is_record) + { + return val->u.record->handle; + } + else + { + return val->u.handle; + } + } + else + { + return NULL; + } + } + break; + + case STRING: + { + return *(char **)value; + } + break; + + case INT: + { + int64_t val = *(int64_t *)value; + snprintf(buf, sizeof(buf), "%"PRId64, val); + return buf; + } + break; + + case ENUM: + { + int val = *(int *)value; + return type->enum_marshaller(val); } break; @@ -1331,7 +1387,19 @@ add_struct_array(xmlNode *struct_node, const char *name) xmlNode *array_node = add_container(value_node, "array"); return add_container(array_node, "data"); +} + + +static xmlNode * +add_nested_struct(xmlNode *struct_node, const char *name) +{ + xmlNode *member_node = add_container(struct_node, "member"); + + xmlNewChild(member_node, NULL, BAD_CAST "name", BAD_CAST name); + + xmlNode *value_node = add_container(member_node, "value"); + return add_container(value_node, "struct"); } |