[libvirt] [PATCH] esx: Make esxVI_*_Deserialize dynamically dispatched

Matthias Bolte matthias.bolte at googlemail.com
Tue Jul 6 18:19:15 UTC 2010


This will be used to deserialize the response from a call
to esxVI_SearchDatastore_Task (to be added in the next patch)
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 8df0e80..ff3e3d1 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 3f34fee..6e75995 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
  */
-- 
1.7.0.4




More information about the libvir-list mailing list