Module: wine Branch: master Commit: 47e7d4bea23ed21bad896547f167a96db2e67e9e URL: https://source.winehq.org/git/wine.git/?a=commit;h=47e7d4bea23ed21bad896547f...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Sep 25 19:22:31 2019 +0200
scrobj: Add property element parser support.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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, ¶meter->name); if (FAILED(hres)) return hres; - list_add_tail(&member->parameters, ¶meter->entry); + list_add_tail(&member->u.parameters, ¶meter->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(¶meter->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(¶meter->entry); + heap_free(parameter->name); + heap_free(parameter); + } } heap_free(member); }