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, ¶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);
}
More information about the wine-cvs
mailing list