ia64/xen-unstable
changeset 13823:0fb5df09de94
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>
and VCPU params.
Signed-off-by: Ewan Mellor <ewan@xensource.com>
author | Ewan Mellor <ewan@xensource.com> |
---|---|
date | Thu Feb 01 19:02:13 2007 +0000 (2007-02-01) |
parents | a357bed2daf8 |
children | 7a50ba45bbf3 |
files | tools/libxen/src/xen_common.c |
line diff
1.1 --- a/tools/libxen/src/xen_common.c Thu Feb 01 19:00:17 2007 +0000 1.2 +++ b/tools/libxen/src/xen_common.c Thu Feb 01 19:02:13 2007 +0000 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2006 XenSource, Inc. 1.6 + * Copyright (c) 2006-2007 XenSource, Inc. 1.7 * 1.8 * This library is free software; you can redistribute it and/or 1.9 * modify it under the terms of the GNU Lesser General Public 1.10 @@ -86,6 +86,8 @@ static xmlNode * 1.11 add_param_struct(xmlNode *); 1.12 static xmlNode * 1.13 add_struct_array(xmlNode *, const char *); 1.14 +static xmlNode * 1.15 +add_nested_struct(xmlNode *, const char *); 1.16 static void 1.17 add_struct_member(xmlNode *, const char *, const char *, const char *); 1.18 static void 1.19 @@ -107,6 +109,9 @@ parse_structmap_value(xen_session *, xml 1.20 1.21 static size_t size_of_member(const abstract_type *); 1.22 1.23 +static const char * 1.24 +get_val_as_string(const struct abstract_type *, void *, char *); 1.25 + 1.26 1.27 void 1.28 xen_init(void) 1.29 @@ -1174,37 +1179,12 @@ add_struct_value(const struct abstract_t 1.30 switch (type->typename) 1.31 { 1.32 case REF: 1.33 + case STRING: 1.34 + case INT: 1.35 + case ENUM: 1.36 { 1.37 - arbitrary_record_opt *val = *(arbitrary_record_opt **)value; 1.38 - if (val != NULL) 1.39 - { 1.40 - if (val->is_record) 1.41 - { 1.42 - adder(node, key, "string", val->u.record->handle); 1.43 - } 1.44 - else 1.45 - { 1.46 - adder(node, key, "string", val->u.handle); 1.47 - } 1.48 - } 1.49 - } 1.50 - break; 1.51 - 1.52 - case STRING: 1.53 - { 1.54 - char *val = *(char **)value; 1.55 - if (val != NULL) 1.56 - { 1.57 - adder(node, key, "string", val); 1.58 - } 1.59 - } 1.60 - break; 1.61 - 1.62 - case INT: 1.63 - { 1.64 - int64_t val = *(int64_t *)value; 1.65 - snprintf(buf, sizeof(buf), "%"PRId64, val); 1.66 - adder(node, key, "string", buf); 1.67 + const char *val_as_string = get_val_as_string(type, value, buf); 1.68 + adder(node, key, "string", val_as_string); 1.69 } 1.70 break; 1.71 1.72 @@ -1223,13 +1203,6 @@ add_struct_value(const struct abstract_t 1.73 } 1.74 break; 1.75 1.76 - case ENUM: 1.77 - { 1.78 - int val = *(int *)value; 1.79 - adder(node, key, "string", type->enum_marshaller(val)); 1.80 - } 1.81 - break; 1.82 - 1.83 case SET: 1.84 { 1.85 const struct abstract_type *member_type = type->child; 1.86 @@ -1251,12 +1224,95 @@ add_struct_value(const struct abstract_t 1.87 break; 1.88 1.89 case STRUCT: 1.90 - case MAP: 1.91 { 1.92 + assert(false); 1.93 /* XXX Nested structures aren't supported yet, but 1.94 fortunately we don't need them, because we don't have 1.95 any "deep create" calls. This will need to be 1.96 - fixed. We don't need maps either. */ 1.97 + fixed. */ 1.98 + } 1.99 + break; 1.100 + 1.101 + case MAP: 1.102 + { 1.103 + size_t member_size = type->struct_size; 1.104 + const struct abstract_type *l_type = type->members[0].type; 1.105 + const struct abstract_type *r_type = type->members[1].type; 1.106 + int l_offset = type->members[0].offset; 1.107 + int r_offset = type->members[1].offset; 1.108 + 1.109 + arbitrary_map *map_val = *(arbitrary_map **)value; 1.110 + 1.111 + if (map_val != NULL) 1.112 + { 1.113 + xmlNode *struct_node = add_nested_struct(node, key); 1.114 + 1.115 + for (size_t i = 0; i < map_val->size; i++) 1.116 + { 1.117 + void *contents = (void *)map_val->contents; 1.118 + void *l_value = contents + (i * member_size) + l_offset; 1.119 + void *r_value = contents + (i * member_size) + r_offset; 1.120 + 1.121 + const char *l_value_as_string = 1.122 + get_val_as_string(l_type, l_value, buf); 1.123 + 1.124 + add_struct_value(r_type, r_value, add_struct_member, 1.125 + l_value_as_string, struct_node); 1.126 + } 1.127 + } 1.128 + } 1.129 + break; 1.130 + 1.131 + default: 1.132 + assert(false); 1.133 + } 1.134 +} 1.135 + 1.136 + 1.137 +static const char * 1.138 +get_val_as_string(const struct abstract_type *type, void *value, char *buf) 1.139 +{ 1.140 + switch (type->typename) 1.141 + { 1.142 + case REF: 1.143 + { 1.144 + arbitrary_record_opt *val = *(arbitrary_record_opt **)value; 1.145 + if (val != NULL) 1.146 + { 1.147 + if (val->is_record) 1.148 + { 1.149 + return val->u.record->handle; 1.150 + } 1.151 + else 1.152 + { 1.153 + return val->u.handle; 1.154 + } 1.155 + } 1.156 + else 1.157 + { 1.158 + return NULL; 1.159 + } 1.160 + } 1.161 + break; 1.162 + 1.163 + case STRING: 1.164 + { 1.165 + return *(char **)value; 1.166 + } 1.167 + break; 1.168 + 1.169 + case INT: 1.170 + { 1.171 + int64_t val = *(int64_t *)value; 1.172 + snprintf(buf, sizeof(buf), "%"PRId64, val); 1.173 + return buf; 1.174 + } 1.175 + break; 1.176 + 1.177 + case ENUM: 1.178 + { 1.179 + int val = *(int *)value; 1.180 + return type->enum_marshaller(val); 1.181 } 1.182 break; 1.183 1.184 @@ -1331,7 +1387,19 @@ add_struct_array(xmlNode *struct_node, c 1.185 xmlNode *array_node = add_container(value_node, "array"); 1.186 1.187 return add_container(array_node, "data"); 1.188 +} 1.189 1.190 + 1.191 +static xmlNode * 1.192 +add_nested_struct(xmlNode *struct_node, const char *name) 1.193 +{ 1.194 + xmlNode *member_node = add_container(struct_node, "member"); 1.195 + 1.196 + xmlNewChild(member_node, NULL, BAD_CAST "name", BAD_CAST name); 1.197 + 1.198 + xmlNode *value_node = add_container(member_node, "value"); 1.199 + 1.200 + return add_container(value_node, "struct"); 1.201 } 1.202 1.203