Jacek Caban : scrobj: Add property element parser support.

Alexandre Julliard julliard at winehq.org
Wed Sep 25 16:45:19 CDT 2019


Module: wine
Branch: master
Commit: 47e7d4bea23ed21bad896547f167a96db2e67e9e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=47e7d4bea23ed21bad896547f167a96db2e67e9e

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep 25 19:22:31 2019 +0200

scrobj: Add property element parser support.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/scrobj/scrobj.c | 143 +++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 116 insertions(+), 27 deletions(-)

diff --git a/dlls/scrobj/scrobj.c b/dlls/scrobj/scrobj.c
index 29116e29b1..736dce9557 100644
--- a/dlls/scrobj/scrobj.c
+++ b/dlls/scrobj/scrobj.c
@@ -55,11 +55,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(scrobj);
 
 static HINSTANCE scrobj_instance;
 
+enum member_type
+{
+    MEMBER_METHOD,
+    MEMBER_PROPERTY
+};
+
+#define PROP_GETTER   0x01
+#define PROP_SETTER   0x02
+
 struct scriptlet_member
 {
     struct list entry;
+    enum member_type type;
     WCHAR *name;
-    struct list parameters;
+    union
+    {
+        struct list parameters;
+        unsigned int flags;
+    } u;
 };
 
 struct method_parameter
@@ -1223,10 +1237,14 @@ static HRESULT parse_scriptlet_registration(struct scriptlet_factory *factory)
 
 static HRESULT parse_scriptlet_public(struct scriptlet_factory *factory)
 {
-    struct scriptlet_member *member;
+    struct scriptlet_member *member, *member_iter;
+    enum member_type member_type;
     XmlNodeType node_type;
+    BOOL empty;
     HRESULT hres;
 
+    TRACE("\n");
+
     if (factory->have_public)
     {
         FIXME("duplicated public element\n");
@@ -1246,29 +1264,53 @@ static HRESULT parse_scriptlet_public(struct scriptlet_factory *factory)
         }
 
         if (is_xml_name(factory, L"method"))
+            member_type = MEMBER_METHOD;
+        else if (is_xml_name(factory, L"property"))
+            member_type = MEMBER_PROPERTY;
+        else
         {
-            hres = IXmlReader_MoveToAttributeByName(factory->xml_reader, L"name", NULL);
-            if (hres != S_OK)
-            {
-                FIXME("Missing method name\n");
-                return E_FAIL;
-            }
+            FIXME("Unexpected element %s\n", debugstr_xml_name(factory));
+            return E_NOTIMPL;
+        }
 
-            if (!(member = heap_alloc(sizeof(*member)))) return E_OUTOFMEMORY;
+        empty = IXmlReader_IsEmptyElement(factory->xml_reader);
 
-            hres = read_xml_value(factory, &member->name);
-            if (FAILED(hres))
+        hres = IXmlReader_MoveToAttributeByName(factory->xml_reader, L"name", NULL);
+        if (hres != S_OK)
+        {
+            FIXME("Missing method name\n");
+            return E_FAIL;
+        }
+
+        if (!(member = heap_alloc(sizeof(*member)))) return E_OUTOFMEMORY;
+        member->type = member_type;
+
+        hres = read_xml_value(factory, &member->name);
+        if (FAILED(hres))
+        {
+            heap_free(member);
+            return hres;
+        }
+
+        LIST_FOR_EACH_ENTRY(member_iter, &factory->members, struct scriptlet_member, entry)
+        {
+            if (!wcsicmp(member_iter->name, member->name))
             {
-                heap_free(member);
-                return hres;
+                FIXME("Duplicated member %s\n", debugstr_w(member->name));
+                return E_FAIL;
             }
-            list_init(&member->parameters);
-            list_add_tail(&factory->members, &member->entry);
+        }
+        list_add_tail(&factory->members, &member->entry);
 
+        switch (member_type)
+        {
+        case MEMBER_METHOD:
+            list_init(&member->u.parameters);
+
+            if (empty) break;
             for (;;)
             {
                 struct method_parameter *parameter;
-                BOOL empty;
 
                 hres = next_xml_node(factory, &node_type);
                 if (FAILED(hres)) return hres;
@@ -1297,14 +1339,58 @@ static HRESULT parse_scriptlet_public(struct scriptlet_factory *factory)
 
                 hres = read_xml_value(factory, &parameter->name);
                 if (FAILED(hres)) return hres;
-                list_add_tail(&member->parameters, &parameter->entry);
+                list_add_tail(&member->u.parameters, &parameter->entry);
                 if (!empty && FAILED(hres = expect_end_element(factory))) return hres;
             }
-        }
-        else
-        {
-            FIXME("Unexpected element %s\n", debugstr_xml_name(factory));
-            return E_NOTIMPL;
+            break;
+
+        case MEMBER_PROPERTY:
+            member->u.flags = 0;
+
+            if (empty) break;
+            for (;;)
+            {
+                hres = next_xml_node(factory, &node_type);
+                if (FAILED(hres)) return hres;
+                if (node_type == XmlNodeType_EndElement) break;
+                if (node_type != XmlNodeType_Element)
+                {
+                    FIXME("Unexpected node type %u\n", node_type);
+                    return E_FAIL;
+                }
+                if (is_case_xml_name(factory, L"get"))
+                {
+                    if (member->u.flags & PROP_GETTER)
+                    {
+                        FIXME("Duplicated getter\n");
+                        return E_FAIL;
+                    }
+                    member->u.flags |= PROP_GETTER;
+                }
+                else if (is_case_xml_name(factory, L"put"))
+                {
+                    if (member->u.flags & PROP_SETTER)
+                    {
+                        FIXME("Duplicated setter\n");
+                        return E_FAIL;
+                    }
+                    member->u.flags |= PROP_SETTER;
+                }
+                else
+                {
+                    FIXME("Unexpected property element %s\n", debugstr_xml_name(factory));
+                    return E_FAIL;
+                }
+
+                empty = IXmlReader_IsEmptyElement(factory->xml_reader);
+                if (!empty && FAILED(hres = expect_end_element(factory))) return hres;
+            }
+            if (!member->u.flags)
+            {
+                FIXME("No getter or setter\n");
+                return E_NOTIMPL;
+            }
+            break;
         }
         if (FAILED(hres)) return hres;
     }
@@ -1499,12 +1585,15 @@ static ULONG WINAPI scriptlet_factory_Release(IClassFactory *iface)
             struct scriptlet_member *member = LIST_ENTRY(list_head(&This->members), struct scriptlet_member, entry);
             list_remove(&member->entry);
             heap_free(member->name);
-            while (!list_empty(&member->parameters))
+            if (member->type == MEMBER_METHOD)
             {
-                struct method_parameter *parameter = LIST_ENTRY(list_head(&member->parameters), struct method_parameter, entry);
-                list_remove(&parameter->entry);
-                heap_free(parameter->name);
-                heap_free(parameter);
+                while (!list_empty(&member->u.parameters))
+                {
+                    struct method_parameter *parameter = LIST_ENTRY(list_head(&member->u.parameters), struct method_parameter, entry);
+                    list_remove(&parameter->entry);
+                    heap_free(parameter->name);
+                    heap_free(parameter);
+                }
             }
             heap_free(member);
         }




More information about the wine-cvs mailing list