From 8aa08ea873a0c2c806209de2e83458903b43635b Mon Sep 17 00:00:00 2001 From: Matthias Bolte Date: Tue, 6 Jul 2010 17:27:05 +0200 Subject: [PATCH] esx: Make esxVI_*_Deserialize dynamically dispatched This will be used to deserialize the response from a call to esxVI_SearchDatastore_Task properly. --- src/esx/esx_vi_generator.py | 45 +++++++++++++++----- src/esx/esx_vi_types.c | 82 ++++++++++++++++++++++++++++++++++++- 2 files changed, 115 insertions(+), 12 deletions(-) diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py index 8df0e8073c..ff3e3d1d69 100755 --- a/src/esx/esx_vi_generator.py +++ b/src/esx/esx_vi_generator.py @@ -469,18 +469,21 @@ class Object: return source - def generate_dynamic_cast_code(self): + def generate_dynamic_cast_code(self, is_first = True): global objects_by_name source = "" if self.extended_by is not None: + if not is_first: + source += "\n" + source += " /* %s */\n" % self.name for extended_by in self.extended_by: source += " ESX_VI__TEMPLATE__DYNAMIC_CAST__ACCEPT(%s)\n" % extended_by for extended_by in self.extended_by: - source += objects_by_name[extended_by].generate_dynamic_cast_code() + source += objects_by_name[extended_by].generate_dynamic_cast_code(False) return source @@ -820,18 +823,38 @@ class Object: source += "ESX_VI__TEMPLATE__LIST__SERIALIZE(%s)\n\n" % self.name # deserilaize - if self.features & Object.FEATURE__DESERIALIZE: - source += "/* esxVI_%s_Deserialize */\n" % self.name - source += "ESX_VI__TEMPLATE__DESERIALIZE(%s,\n" % self.name - source += "{\n" + if self.extended_by is None: + if self.features & Object.FEATURE__DESERIALIZE: + source += "/* esxVI_%s_Deserialize */\n" % self.name + source += "ESX_VI__TEMPLATE__DESERIALIZE(%s,\n" % self.name + source += "{\n" - source += self.generate_deserialize_code() + source += self.generate_deserialize_code() - source += "})\n\n" + source += "})\n\n" - if self.features & Object.FEATURE__LIST: - source += "/* esxVI_%s_DeserializeList */\n" % self.name - source += "ESX_VI__TEMPLATE__LIST__DESERIALIZE(%s)\n\n" % self.name + if self.features & Object.FEATURE__LIST: + source += "/* esxVI_%s_DeserializeList */\n" % self.name + source += "ESX_VI__TEMPLATE__LIST__DESERIALIZE(%s)\n\n" % self.name + else: + if self.features & Object.FEATURE__DESERIALIZE: + source += "/* esxVI_%s_Deserialize */\n" % self.name + source += "ESX_VI__TEMPLATE__DYNAMIC_DESERIALIZE(%s,\n" % self.name + source += "{\n" + + for extended_by in self.extended_by: + source += " ESX_VI__TEMPLATE__DISPATCH__DESERIALIZE(%s)\n" % extended_by + + source += "},\n" + source += "{\n" + + source += self.generate_deserialize_code() + + source += "})\n\n" + + if self.features & Object.FEATURE__LIST: + source += "/* esxVI_%s_DeserializeList */\n" % self.name + source += "ESX_VI__TEMPLATE__LIST__DESERIALIZE(%s)\n\n" % self.name source += "\n\n" diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c index 3f34fee60f..6e759950a9 100644 --- a/src/esx/esx_vi_types.c +++ b/src/esx/esx_vi_types.c @@ -250,12 +250,14 @@ -#define ESX_VI__TEMPLATE__DESERIALIZE(_type, _deserialize) \ +#define ESX_VI__TEMPLATE__DESERIALIZE_EXTRA(_type, _extra, _deserialize) \ int \ esxVI_##_type##_Deserialize(xmlNodePtr node, esxVI_##_type **ptrptr) \ { \ xmlNodePtr childNode = NULL; \ \ + _extra \ + \ if (ptrptr == NULL || *ptrptr != NULL) { \ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", \ _("Invalid argument")); \ @@ -293,6 +295,11 @@ +#define ESX_VI__TEMPLATE__DESERIALIZE(_type, _deserialize) \ + ESX_VI__TEMPLATE__DESERIALIZE_EXTRA(_type, /* nothing */, _deserialize) + + + #define ESX_VI__TEMPLATE__DESERIALIZE_NUMBER(_type, _xsdType, _min, _max) \ int \ esxVI_##_type##_Deserialize(xmlNodePtr node, esxVI_##_type **number) \ @@ -544,6 +551,12 @@ +#define ESX_VI__TEMPLATE__DISPATCH__DESERIALIZE(_type) \ + case esxVI_Type_##_type: \ + return esxVI_##_type##_Deserialize(node, (esxVI_##_type **)ptrptr); + + + #define ESX_VI__TEMPLATE__DYNAMIC_FREE(__type, _dispatch, _body) \ ESX_VI__TEMPLATE__FREE(__type, \ ESX_VI__TEMPLATE__DISPATCH(__type, _dispatch, /* nothing */) \ @@ -584,6 +597,73 @@ +#define ESX_VI__TEMPLATE__DYNAMIC_DESERIALIZE(__type, _dispatch, \ + _deserialize) \ + ESX_VI__TEMPLATE__DESERIALIZE_EXTRA(__type, \ + esxVI_Type type = esxVI_Type_Undefined; \ + \ + if (esxVI_GetActualObjectType(node, esxVI_Type_##__type, &type) < 0) { \ + return -1; \ + } \ + \ + switch (type) { \ + _dispatch \ + \ + case esxVI_Type_##__type: \ + break; \ + \ + default: \ + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, \ + _("Call to %s for unexpected type '%s'"), \ + __FUNCTION__, esxVI_Type_ToString(type)); \ + return -1; \ + }, \ + _deserialize) + + + +static int +esxVI_GetActualObjectType(xmlNodePtr node, esxVI_Type baseType, + esxVI_Type *actualType) +{ + int result = -1; + char *type = NULL; + + if (actualType == NULL || *actualType != esxVI_Type_Undefined) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument")); + return -1; + } + + type = (char *)xmlGetNsProp + (node, BAD_CAST "type", + BAD_CAST "http://www.w3.org/2001/XMLSchema-instance"); + + if (type == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, + _("%s is missing 'type' property"), + esxVI_Type_ToString(baseType)); + return -1; + } + + *actualType = esxVI_Type_FromString(type); + + if (*actualType == esxVI_Type_Undefined) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, + _("Unknown value '%s' for %s 'type' property"), + type, esxVI_Type_ToString(baseType)); + goto cleanup; + } + + result = 0; + + cleanup: + VIR_FREE(type); + + return result; +} + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * XSI: Type */