216 lines
5.5 KiB
Diff
216 lines
5.5 KiB
Diff
# HG changeset patch
|
|
# User Ewan Mellor <ewan@xensource.com>
|
|
# Date 1170356533 0
|
|
# Node ID 0fb5df09de9426b9144eabc0d9a93c0bbfe14070
|
|
# Parent a357bed2daf8096bb5c682d454a2b3af652fc73f
|
|
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>
|
|
|
|
diff -r a357bed2daf8 -r 0fb5df09de94 tools/libxen/src/xen_common.c
|
|
--- a/tools/libxen/src/xen_common.c Thu Feb 01 19:00:17 2007 +0000
|
|
+++ b/tools/libxen/src/xen_common.c Thu Feb 01 19:02:13 2007 +0000
|
|
@@ -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 @@ add_param_struct(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
|
|
@@ -106,6 +108,9 @@ parse_structmap_value(xen_session *, xml
|
|
void *);
|
|
|
|
static size_t size_of_member(const abstract_type *);
|
|
+
|
|
+static const char *
|
|
+get_val_as_string(const struct abstract_type *, void *, char *);
|
|
|
|
|
|
void
|
|
@@ -1174,37 +1179,12 @@ add_struct_value(const struct abstract_t
|
|
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:
|
|
- {
|
|
- int64_t val = *(int64_t *)value;
|
|
- snprintf(buf, sizeof(buf), "%"PRId64, val);
|
|
- adder(node, key, "string", buf);
|
|
+ case ENUM:
|
|
+ {
|
|
+ const char *val_as_string = get_val_as_string(type, value, buf);
|
|
+ adder(node, key, "string", val_as_string);
|
|
}
|
|
break;
|
|
|
|
@@ -1220,13 +1200,6 @@ add_struct_value(const struct abstract_t
|
|
{
|
|
bool val = *(bool *)value;
|
|
adder(node, key, "boolean", val ? "1" : "0");
|
|
- }
|
|
- break;
|
|
-
|
|
- case ENUM:
|
|
- {
|
|
- int val = *(int *)value;
|
|
- adder(node, key, "string", type->enum_marshaller(val));
|
|
}
|
|
break;
|
|
|
|
@@ -1251,12 +1224,95 @@ add_struct_value(const struct abstract_t
|
|
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, c
|
|
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");
|
|
}
|
|
|
|
|