aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxen
diff options
context:
space:
mode:
authorEwan Mellor <ewan@xensource.com>2007-02-01 19:02:13 +0000
committerEwan Mellor <ewan@xensource.com>2007-02-01 19:02:13 +0000
commit948fd9f5a1e8db844b1a1f0a0fec93f5a29434cc (patch)
tree3d430a367897aac5cdbf2cfe96ce9b45b4e2116b /tools/libxen
parentf72dfefae2eeaa789f23cc77787f5d18d253837b (diff)
downloadxen-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/libxen')
-rw-r--r--tools/libxen/src/xen_common.c144
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");
}