direct-io.hg

changeset 13787: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>
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