[PATCH v3 0/8] MR10599: msxml3/tests: Add some more xml() tests.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> -- v3: msxml3: Rework DOM API. https://gitlab.winehq.org/wine/wine/-/merge_requests/10599
From: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/msxml3/tests/domdoc.c | 61 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 4dd1516f3a6..bbe43c652a4 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -8901,6 +8901,67 @@ static void test_get_xml(void) "Unexpected xml %s.\n", wine_dbgstr_w(xml)); SysFreeString(xml); + /* Default namespace */ + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a><elem xmlns=\"http://blah.org\" /></a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocument_get_xml(doc, &xml); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(xml, L"<a><elem xmlns=\"http://blah.org\"/></a>\r\n"), + "Unexpected xml %s.\n", wine_dbgstr_w(xml)); + SysFreeString(xml); + + /* Load with preservedWhiteSpace == FALSE */ + hr = IXMLDOMDocument_put_preserveWhiteSpace(doc, VARIANT_FALSE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a> </a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocument_get_documentElement(doc, &elem); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + EXPECT_NO_CHILDREN(elem); + + hr = IXMLDOMElement_get_xml(elem, &xml); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(xml, L"<a>\r\n</a>"), "Unexpected text %s.\n", debugstr_w(xml)); + SysFreeString(xml); + + hr = IXMLDOMDocument_put_preserveWhiteSpace(doc, VARIANT_TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_xml(elem, &xml); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(xml, L"<a>\r\n</a>"), "Unexpected text %s.\n", debugstr_w(xml)); + SysFreeString(xml); + IXMLDOMElement_Release(elem); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a></a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocument_get_documentElement(doc, &elem); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_xml(elem, &xml); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(xml, L"<a></a>"), "Unexpected text %s.\n", debugstr_w(xml)); + SysFreeString(xml); + IXMLDOMElement_Release(elem); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a/>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocument_get_documentElement(doc, &elem); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_xml(elem, &xml); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(xml, L"<a/>"), "Unexpected text %s.\n", debugstr_w(xml)); + SysFreeString(xml); + IXMLDOMElement_Release(elem); + IXMLDOMDocument_Release(doc); free_bstrs(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10599
From: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/msxml3/tests/domdoc.c | 140 +++++++++++++++++++++++++++++++++---- 1 file changed, 125 insertions(+), 15 deletions(-) diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index bbe43c652a4..42e859a483a 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -3611,9 +3611,9 @@ static void test_get_text(void) VARIANT_BOOL b; IXMLDOMDocument *doc; IXMLDOMNode *node, *node2, *node3; - IXMLDOMNode *nodeRoot; IXMLDOMNodeList *node_list; IXMLDOMNamedNodeMap *node_map; + IXMLDOMElement *element; HRESULT hr; LONG len; @@ -3623,23 +3623,36 @@ static void test_get_text(void) ok(hr == S_OK, "loadXML failed\n"); ok( b == VARIANT_TRUE, "failed to load XML string\n"); - str = SysAllocString( L"bs" ); - hr = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list ); + /* Test to get all child node text. */ + hr = IXMLDOMDocument_get_text(doc, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"fn1.txt\n \nfn2.txt\n \nf1"), "Unexpected text %s.\n", debugstr_w(str)); SysFreeString(str); - /* Test to get all child node text. */ - hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot); + hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("lc"), &node_list); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - hr = IXMLDOMNode_get_text( nodeRoot, &str ); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - ok(!wcscmp(str, L"fn1.txt\n \nfn2.txt\n \nf1"), "Unexpected text %s.\n", debugstr_w(str)); - SysFreeString(str); + hr = IXMLDOMNodeList_get_item(node_list, 0, &node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNode_get_text(node, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"fn1.txt\n \nfn2.txt\n \nf1"), "Unexpected text %s.\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + IXMLDOMNodeList_Release(node_list); - IXMLDOMNode_Release(nodeRoot); - } + hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("pr"), &node_list); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNodeList_get_item(node_list, 0, &node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNode_get_text(node, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"fn2.txt"), "Unexpected text %s.\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + IXMLDOMNodeList_Release(node_list); + + hr = IXMLDOMDocument_getElementsByTagName( doc, _bstr_("bs"), &node_list ); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMNodeList_get_length( node_list, NULL ); ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); @@ -3688,12 +3701,109 @@ static void test_get_text(void) ok( !lstrcmpW(str, L"str2"), "Unexpected string.\n" ); SysFreeString(str); - IXMLDOMNode_Release( node3 ); IXMLDOMNode_Release( node2 ); IXMLDOMNamedNodeMap_Release( node_map ); IXMLDOMNode_Release( node ); - IXMLDOMDocument_Release( doc ); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a>\n <![CDATA[a]]> This is <![CDATA[b]]> c </a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_text(element, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"a This is b c"), "%s\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMElement_Release(element); + + /* Empty sections */ + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a>\n <![CDATA[]]> This is <![CDATA[]]> c </a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_text(element, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L" This is c"), "%s\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMElement_Release(element); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a>\n <![CDATA[]]> This is <![CDATA[]]> <![CDATA[]]>b</a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_text(element, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L" This is b"), "%s\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMElement_Release(element); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a>\n <![CDATA[]]> This is <![CDATA[]]> <![CDATA[]]> </a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_text(element, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(str, L" This is"), "%s\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMElement_Release(element); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a>\n <b/> This is </a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_text(element, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"This is"), "%s\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMElement_Release(element); + + /* Separated with PI */ + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a>\n a <?pi ?> This is </a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_text(element, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"a This is"), "%s\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMElement_Release(element); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a><?pi p?> This is </a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_text(element, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"This is"), "%s\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMElement_Release(element); + + /* Deeper nesting level */ + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a>a <b> b <![CDATA[]]> This is </b></a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_text(element, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"a b This is"), "%s\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMElement_Release(element); + + /* Nested elements, first text node is not an immediate child. */ + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a><b> b </b> a </a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_text(element, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"b a"), "%s\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMElement_Release(element); + + IXMLDOMDocument_Release(doc); free_bstrs(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10599
From: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/msxml3/tests/domdoc.c | 164 ++++++++++++++++++++++++++++++++++++- 1 file changed, 161 insertions(+), 3 deletions(-) diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 42e859a483a..644ceec90d5 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -5080,15 +5080,173 @@ static const struct whitespace_t whitespace_test_data[] = { static void test_whitespace(void) { const struct whitespace_t *class_ptr = whitespace_test_data; + IXMLDOMElement *element; + IXMLDOMNodeList *list; + IXMLDOMDocument *doc; + IXMLDOMNode *node, *node2; + VARIANT_BOOL b; + HRESULT hr; + BSTR text; + LONG len; + + hr = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void **)&doc); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* Load with preservedWhiteSpace == FALSE */ + hr = IXMLDOMDocument_put_preserveWhiteSpace(doc, VARIANT_FALSE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a> </a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMElement_get_childNodes(element, &list); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNodeList_get_length(list, &len); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!len, "Unexpected length %ld.\n", len); + IXMLDOMNodeList_Release(list); + + hr = IXMLDOMElement_get_xml(element, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(text, L"<a>\r\n</a>"), "Unexpected text %s.\n", debugstr_w(text)); + SysFreeString(text); + + hr = IXMLDOMElement_get_text(element, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L""), "Unexpected text %s.\n", debugstr_w(text)); + SysFreeString(text); + + hr = IXMLDOMDocument_put_preserveWhiteSpace(doc, VARIANT_TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMElement_get_text(element, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L""), "Unexpected text %s.\n", debugstr_w(text)); + SysFreeString(text); + + IXMLDOMElement_Release(element); + + hr = IXMLDOMDocument_put_preserveWhiteSpace(doc, VARIANT_TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a> a<b> </b>c </a>"), &b); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMElement_get_childNodes(element, &list); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMNodeList_nextNode(list, &node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNode_get_text(node, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L" a"), "Unexpected text %s.\n", debugstr_w(text)); + IXMLDOMNode_Release(node); + SysFreeString(text); + + hr = IXMLDOMNodeList_nextNode(list, &node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNode_get_text(node, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L" "), "Unexpected text %s.\n", debugstr_w(text)); + { + IXMLDOMNodeList *list; + + hr = IXMLDOMNode_get_childNodes(node, &list); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMNodeList_nextNode(list, &node2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNode_get_text(node2, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L" "), "Unexpected text %s.\n", debugstr_w(text)); + SysFreeString(text); + IXMLDOMNode_Release(node2); + + IXMLDOMNodeList_Release(list); + } + IXMLDOMNode_Release(node); + SysFreeString(text); + + hr = IXMLDOMNodeList_nextNode(list, &node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNode_get_text(node, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L"c "), "Unexpected text %s.\n", debugstr_w(text)); + IXMLDOMNode_Release(node); + SysFreeString(text); + + hr = IXMLDOMElement_get_text(element, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L" a c "), "Unexpected text %s.\n", debugstr_w(text)); + SysFreeString(text); + + hr = IXMLDOMDocument_put_preserveWhiteSpace(doc, VARIANT_FALSE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMNodeList_reset(list); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMNodeList_nextNode(list, &node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNode_get_text(node, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L"a"), "Unexpected text %s.\n", debugstr_w(text)); + IXMLDOMNode_Release(node); + SysFreeString(text); + + hr = IXMLDOMNodeList_nextNode(list, &node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNode_get_text(node, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L""), "Unexpected text %s.\n", debugstr_w(text)); + { + IXMLDOMNodeList *list; + + hr = IXMLDOMNode_get_childNodes(node, &list); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMNodeList_nextNode(list, &node2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNode_get_text(node2, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L""), "Unexpected text %s.\n", debugstr_w(text)); + SysFreeString(text); + IXMLDOMNode_Release(node2); + + IXMLDOMNodeList_Release(list); + } + IXMLDOMNode_Release(node); + SysFreeString(text); + + hr = IXMLDOMNodeList_nextNode(list, &node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNode_get_text(node, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L"c"), "Unexpected text %s.\n", debugstr_w(text)); + IXMLDOMNode_Release(node); + SysFreeString(text); + + hr = IXMLDOMElement_get_text(element, &text); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(text, L"a c"), "Unexpected text %s.\n", debugstr_w(text)); + SysFreeString(text); + + IXMLDOMNodeList_Release(list); + IXMLDOMElement_Release(element); + IXMLDOMDocument_Release(doc); while (class_ptr->clsid) { IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4; IXMLDOMNodeList *list; IXMLDOMElement *root; - VARIANT_BOOL b; - HRESULT hr; - LONG len; if (!is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument2)) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10599
From: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/msxml3/tests/domdoc.c | 60 ++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 644ceec90d5..be753b700cb 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -6673,43 +6673,35 @@ static void test_testTransforms(void) free_bstrs(); } -struct namespaces_change_t { - const CLSID *clsid; - const char *name; -}; - -static const struct namespaces_change_t namespaces_change_test_data[] = { - { &CLSID_DOMDocument, "CLSID_DOMDocument" }, - { &CLSID_DOMDocument2, "CLSID_DOMDocument2" }, - { &CLSID_DOMDocument26, "CLSID_DOMDocument26" }, - { &CLSID_DOMDocument30, "CLSID_DOMDocument30" }, - { &CLSID_DOMDocument40, "CLSID_DOMDocument40" }, - { &CLSID_DOMDocument60, "CLSID_DOMDocument60" }, - { 0 } -}; - static void test_namespaces_change(void) { - const struct namespaces_change_t *class_ptr = namespaces_change_test_data; + static const GUID *classes[] = + { + &CLSID_DOMDocument, + &CLSID_DOMDocument2, + &CLSID_DOMDocument26, + &CLSID_DOMDocument30, + &CLSID_DOMDocument40, + &CLSID_DOMDocument60, + NULL, + }; - while (class_ptr->clsid) + for (int i = 0; i < ARRAYSIZE(classes); ++i) { IXMLDOMDocument *doc = NULL; IXMLDOMElement *elem = NULL; IXMLDOMNode *node = NULL; + IXMLDOMNamedNodeMap *map; VARIANT var; HRESULT hr; BSTR str; + LONG len; - if (!is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument)) - { - class_ptr++; + if (!is_clsid_supported(classes[i], &IID_IXMLDOMDocument)) continue; - } - hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER, - &IID_IXMLDOMDocument, (void**)&doc); + hr = CoCreateInstance(classes[i], NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void **)&doc); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); V_VT(&var) = VT_I2; @@ -6724,26 +6716,38 @@ static void test_namespaces_change(void) hr = IXMLDOMDocument_get_documentElement(doc, &elem); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_attributes(elem, &map); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNamedNodeMap_get_length(map, &len); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!len, "Unexpected length %ld.\n", len); + IXMLDOMNamedNodeMap_Release(map); + /* try same prefix, different uri */ hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), _variantbstr_("ns/uri2")); ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); - /* try same prefix and uri */ + /* Same prefix and uri create an explict attribute for implicitly defined namespace. */ hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), _variantbstr_("ns/uri")); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMElement_get_attributes(elem, &map); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMNamedNodeMap_get_length(map, &len); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(len == 1, "Unexpected length %ld.\n", len); + IXMLDOMNamedNodeMap_Release(map); + hr = IXMLDOMElement_get_xml(elem, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - ok(!lstrcmpW(str, L"<ns:elem xmlns:ns=\"ns/uri\"/>"), "got element %s for %s\n", - wine_dbgstr_w(str), class_ptr->name); + ok(!lstrcmpW(str, L"<ns:elem xmlns:ns=\"ns/uri\"/>"), "Unexpected element %s.\n", wine_dbgstr_w(str)); SysFreeString(str); IXMLDOMElement_Release(elem); IXMLDOMDocument_Release(doc); free_bstrs(); - - class_ptr++; } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10599
From: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/msxml3/tests/domdoc.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index be753b700cb..f77e211066f 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -10042,13 +10042,34 @@ static void test_get_doctype(void) todo_wine ok(V_VT(&v) == VT_NULL, "Unexpected type %d.\n", V_VT(&v)); + hr = IXMLDOMDocumentType_get_text(doctype, NULL); + todo_wine + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMDocumentType_get_text(doctype, &s); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!*s, "Unexpected text %s\n", wine_dbgstr_w(s)); + SysFreeString(s); + hr = IXMLDOMDocumentType_get_nodeName(doctype, &s); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(!lstrcmpW(L"email", s), "got name %s\n", wine_dbgstr_w(s)); SysFreeString(s); + /* The 'xml' property contains original doctype text as-is, with newlines normalized */ + hr = IXMLDOMDocumentType_get_xml(doctype, &s); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(s, _bstr_(SZ_EMAIL_DTD)), "Unexpected text %s\n", wine_dbgstr_w(s)); + SysFreeString(s); + IXMLDOMDocumentType_Release(doctype); + IXMLDOMDocument_Release(doc); + free_bstrs(); } static void test_get_tagName(void) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10599
From: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/msxml3/tests/domdoc.c | 100 +++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index f77e211066f..355268625e9 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -16067,6 +16067,7 @@ static void test_xmldecl_attributes(void) { IXMLDOMProcessingInstruction *pi; IXMLDOMNamedNodeMap *map; + IXMLDOMAttribute *attr; IXMLDOMDocument *doc; IXMLDOMNode *node; VARIANT_BOOL b; @@ -16087,6 +16088,11 @@ static void test_xmldecl_attributes(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); IXMLDOMNode_Release(node); + hr = IXMLDOMProcessingInstruction_get_text(pi, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\""), "Unexpected text %s.\n", debugstr_w(str)); + SysFreeString(str); + hr = IXMLDOMProcessingInstruction_get_attributes(pi, &map); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -16145,6 +16151,100 @@ static void test_xmldecl_attributes(void) ok(!wcscmp(str, L"<?xml version=\"1.0\"?>"), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); + hr = IXMLDOMDocument_createAttribute(doc, _bstr_("standalone"), &attr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMAttribute_put_text(attr, _bstr_("no")); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode *)attr, NULL); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) + IXMLDOMAttribute_Release(attr); + + hr = IXMLDOMProcessingInstruction_get_xml(pi, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(str, L"<?xml version=\"1.0\" standalone=\"no\"?>"), "Unexpected string %s.\n", debugstr_w(str)); + SysFreeString(str); + + hr = IXMLDOMProcessingInstruction_get_text(pi, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(str, L"standalone=\"no\""), "Unexpected string %s.\n", debugstr_w(str)); + SysFreeString(str); + + hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMAttribute_put_text(attr, _bstr_("utf-8")); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode *)attr, NULL); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IXMLDOMAttribute_Release(attr); + + hr = IXMLDOMNamedNodeMap_get_length(map, &length); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(length == 2, "Unexpected length %ld.\n", length); + + hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +if (hr == S_OK) +{ + hr = IXMLDOMNode_get_nodeName(node, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"standalone"), "Unexpected name %s.\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); +} + hr = IXMLDOMNamedNodeMap_get_item(map, 1, &node); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +if (hr == S_OK) +{ + hr = IXMLDOMNode_get_nodeName(node, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(str, L"encoding"), "Unexpected name %s.\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); +} + hr = IXMLDOMProcessingInstruction_get_text(pi, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(str, L"standalone=\"no\" encoding=\"utf-8\""), "Unexpected string %s.\n", debugstr_w(str)); + SysFreeString(str); + + hr = IXMLDOMProcessingInstruction_get_xml(pi, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(str, L"<?xml version=\"1.0\" standalone=\"no\"?>"), "Unexpected string %s.\n", debugstr_w(str)); + SysFreeString(str); + + hr = IXMLDOMDocument_createAttribute(doc, _bstr_("version"), &attr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMAttribute_put_text(attr, _bstr_("2.0abc")); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode *)attr, NULL); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IXMLDOMAttribute_Release(attr); + + hr = IXMLDOMProcessingInstruction_get_text(pi, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(str, L"standalone=\"no\" encoding=\"utf-8\" version=\"2.0abc\""), "Unexpected string %s.\n", debugstr_w(str)); + SysFreeString(str); + + hr = IXMLDOMProcessingInstruction_get_xml(pi, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(str, L"<?xml version=\"2.0abc\" standalone=\"no\"?>"), "Unexpected string %s.\n", debugstr_w(str)); + SysFreeString(str); + IXMLDOMNamedNodeMap_Release(map); IXMLDOMProcessingInstruction_Release(pi); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10599
From: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/msxml3/tests/saxreader.c | 58 +++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c index 16f4448a75c..353e48fabe1 100644 --- a/dlls/msxml3/tests/saxreader.c +++ b/dlls/msxml3/tests/saxreader.c @@ -3385,6 +3385,9 @@ static void test_saxreader_encoding(void) '<','a','>','t','e','x','t','<','/','a','>', }; + static const char xml_win936_test[] = + "<?xml version=\"1.0\" encoding=\"windows-936\" ?><a>text</a>"; + static const char xml_win1252_test[] = "<?xml version=\"1.0\" encoding=\"windows-1252\" ?><a>" "\xc1" "\x80" "</a>"; @@ -3456,6 +3459,13 @@ static void test_saxreader_encoding(void) hr = ISAXXMLReader_putContentHandler(reader, &contentHandler); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + create_test_file(testXmlA, xml_win936_test, sizeof(xml_win936_test) - 1); + hr = ISAXXMLReader_parseURL(reader, L"test.xml"); + todo_wine + ok(FAILED(hr), "Unexpected hr %#lx.\n", hr); + flush_sequence(sequences, CONTENT_HANDLER_INDEX); + DeleteFileA(testXmlA); + create_test_file(testXmlA, xml_win1252_test, sizeof(xml_win1252_test) - 1); set_expected_seq(xml_win1252_seq); hr = ISAXXMLReader_parseURL(reader, L"test.xml"); @@ -5316,6 +5326,26 @@ static void test_mxwriter_comment(void) ok(!lstrcmpW(L"<!---->\r\n<!--comment-->\r\n", V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest))); VariantClear(&dest); + /* As an element child */ + V_VT(&dest) = VT_EMPTY; + hr = IMXWriter_put_output(writer, dest); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = ISAXContentHandler_startElement(content, L"", 0, L"", 0, _bstr_("a"), -1, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = ISAXLexicalHandler_comment(lexical, L"comment", 7); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = ISAXContentHandler_endElement(content, L"", 0, L"", 0, _bstr_("a"), -1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + V_VT(&dest) = VT_EMPTY; + hr = IMXWriter_get_output(writer, &dest); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(V_VT(&dest) == VT_BSTR, "Unexpected type %d.\n", V_VT(&dest)); + todo_wine + ok(!lstrcmpW(L"<a><!--comment--></a>", V_BSTR(&dest)), "Unexpected content %s.\n", wine_dbgstr_w(V_BSTR(&dest))); + VariantClear(&dest); + ISAXContentHandler_Release(content); ISAXLexicalHandler_Release(lexical); IVBSAXLexicalHandler_Release(vblexical); @@ -6396,6 +6426,33 @@ static void test_saxreader_dtd(void) hr = ISAXXMLReader_parse(reader, var); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(L"<?xml version=\"1.0\" encoding=\"value\" standalone=\"yes\"?><a>text</a>"); + + hr = ISAXXMLReader_parse(reader, var); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + VariantClear(&var); + + ISAXXMLReader_Release(reader); +} + +static void test_saxreader_parse_input(void) +{ + ISAXXMLReader *reader; + VARIANT var; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER, &IID_ISAXXMLReader, (void **)&reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocStringByteLen("<a>text</a>", 11); + + hr = ISAXXMLReader_parse(reader, var); + todo_wine + ok(FAILED(hr), "Unexpected hr %#lx.\n", hr); + VariantClear(&var); ISAXXMLReader_Release(reader); @@ -6437,6 +6494,7 @@ START_TEST(saxreader) test_saxreader_pi(); test_saxreader_characters(); test_saxreader_dtd(); + test_saxreader_parse_input(); /* MXXMLWriter tests */ get_class_support_data(mxwriter_support_data, &IID_IMXWriter); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10599
From: Nikolay Sivov <nsivov@codeweavers.com> For the most parts this touches only tree API. Validation, XPath, XSLT, and schema handling is still going through libxml2 at the moment. Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/msxml3/Makefile.in | 1 + dlls/msxml3/attribute.c | 635 ++- dlls/msxml3/cdata.c | 543 +-- dlls/msxml3/comment.c | 584 ++- dlls/msxml3/docfrag.c | 612 ++- dlls/msxml3/doctype.c | 474 +-- dlls/msxml3/domdoc.c | 2777 ++++--------- dlls/msxml3/domimpl.c | 93 +- dlls/msxml3/element.c | 1431 ++----- dlls/msxml3/entityref.c | 522 ++- dlls/msxml3/msxml_private.h | 281 +- dlls/msxml3/mxwriter.c | 11 + dlls/msxml3/node.c | 5611 +++++++++++++++++--------- dlls/msxml3/nodelist.c | 263 +- dlls/msxml3/nodemap.c | 270 +- dlls/msxml3/pi.c | 852 ++-- dlls/msxml3/saxreader.c | 638 ++- dlls/msxml3/saxreader_extensions.idl | 44 + dlls/msxml3/schema.c | 356 +- dlls/msxml3/selection.c | 485 +-- dlls/msxml3/stylesheet.c | 33 +- dlls/msxml3/tests/domdoc.c | 153 +- dlls/msxml3/tests/saxreader.c | 2 - dlls/msxml3/tests/xmldoc.c | 1 - dlls/msxml3/text.c | 586 ++- dlls/msxml3/xmldoc.c | 9 +- dlls/msxml4/tests/saxreader.c | 13 +- dlls/msxml6/tests/saxreader.c | 13 +- libs/xml2/include/libxml/tree.h | 7 + libs/xml2/xpath.c | 1 + 30 files changed, 8225 insertions(+), 9076 deletions(-) create mode 100644 dlls/msxml3/saxreader_extensions.idl diff --git a/dlls/msxml3/Makefile.in b/dlls/msxml3/Makefile.in index a373417df89..ff946de9fdd 100644 --- a/dlls/msxml3/Makefile.in +++ b/dlls/msxml3/Makefile.in @@ -32,6 +32,7 @@ SOURCES = \ pi.c \ rsrc.rc \ saxreader.c \ + saxreader_extensions.idl \ schema.c \ schemas.rc \ selection.c \ diff --git a/dlls/msxml3/attribute.c b/dlls/msxml3/attribute.c index a183a504e66..4842b6cc050 100644 --- a/dlls/msxml3/attribute.c +++ b/dlls/msxml3/attribute.c @@ -21,9 +21,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> -#include <libxml/HTMLtree.h> #include "windef.h" #include "winbase.h" @@ -37,17 +34,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); -static const xmlChar xmlns[] = "xmlns"; - typedef struct _domattr { - xmlnode node; + DispatchEx dispex; IXMLDOMAttribute IXMLDOMAttribute_iface; - LONG ref; - BOOL floating; + LONG refcount; + struct domnode *node; } domattr; -static const tid_t domattr_se_tids[] = { +static const tid_t domattr_se_tids[] = +{ IXMLDOMNode_tid, IXMLDOMAttribute_tid, NULL_tid @@ -58,33 +54,35 @@ static inline domattr *impl_from_IXMLDOMAttribute( IXMLDOMAttribute *iface ) return CONTAINING_RECORD(iface, domattr, IXMLDOMAttribute_iface); } -static HRESULT WINAPI domattr_QueryInterface( - IXMLDOMAttribute *iface, - REFIID riid, - void** ppvObject ) +static HRESULT WINAPI domattr_QueryInterface(IXMLDOMAttribute *iface, REFIID riid, void **obj) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); - if ( IsEqualGUID( riid, &IID_IXMLDOMAttribute ) || - IsEqualGUID( riid, &IID_IXMLDOMNode ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IUnknown ) ) + if (IsEqualGUID(riid, &IID_IXMLDOMAttribute) || + IsEqualGUID(riid, &IID_IXMLDOMNode) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IUnknown)) + { + *obj = iface; + } + else if (dispex_query_interface(&attr->dispex, riid, obj)) { - *ppvObject = iface; + return *obj ? S_OK : E_NOINTERFACE; } - else if(node_query_interface(&This->node, riid, ppvObject)) + else if (node_query_interface(attr->node, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } - else if(IsEqualGUID( riid, &IID_ISupportErrorInfo )) + else if (IsEqualGUID(riid, &IID_ISupportErrorInfo)) { - return node_create_supporterrorinfo(domattr_se_tids, ppvObject); + return node_create_supporterrorinfo(domattr_se_tids, obj); } else { TRACE("Unsupported interface %s\n", debugstr_guid(riid)); - *ppvObject = NULL; + *obj = NULL; return E_NOINTERFACE; } @@ -92,343 +90,262 @@ static HRESULT WINAPI domattr_QueryInterface( return S_OK; } -static ULONG WINAPI domattr_AddRef( - IXMLDOMAttribute *iface ) +static ULONG WINAPI domattr_AddRef(IXMLDOMAttribute *iface) { - domattr *attr = impl_from_IXMLDOMAttribute( iface ); - ULONG ref = InterlockedIncrement( &attr->ref ); - TRACE("%p, refcount %lu.\n", iface, ref); - return ref; + domattr *attr = impl_from_IXMLDOMAttribute(iface); + ULONG refcount = InterlockedIncrement(&attr->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); + + return refcount; } -static ULONG WINAPI domattr_Release( - IXMLDOMAttribute *iface ) +static ULONG WINAPI domattr_Release(IXMLDOMAttribute *iface) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - ULONG ref = InterlockedDecrement( &This->ref ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + ULONG refcount = InterlockedDecrement(&attr->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); - TRACE("%p, refcount %lu.\n", iface, ref); - if ( ref == 0 ) + if (!refcount) { - destroy_xmlnode(&This->node); - if ( This->floating ) - { - xmlFreeNs( This->node.node->ns ); - xmlFreeNode( This->node.node ); - } - free( This ); + domnode_release(attr->node); + free(attr); } - return ref; + return refcount; } -static HRESULT WINAPI domattr_GetTypeInfoCount( - IXMLDOMAttribute *iface, - UINT* pctinfo ) +static HRESULT WINAPI domattr_GetTypeInfoCount(IXMLDOMAttribute *iface, UINT *count) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + return IDispatchEx_GetTypeInfoCount(&attr->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI domattr_GetTypeInfo( - IXMLDOMAttribute *iface, - UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI domattr_GetTypeInfo(IXMLDOMAttribute *iface, UINT index, LCID lcid, ITypeInfo **ti) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + return IDispatchEx_GetTypeInfo(&attr->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI domattr_GetIDsOfNames( - IXMLDOMAttribute *iface, - REFIID riid, LPOLESTR* rgszNames, - UINT cNames, LCID lcid, DISPID* rgDispId ) +static HRESULT WINAPI domattr_GetIDsOfNames(IXMLDOMAttribute *iface, REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, + domattr *attr = impl_from_IXMLDOMAttribute(iface); + return IDispatchEx_GetIDsOfNames(&attr->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); } -static HRESULT WINAPI domattr_Invoke( - IXMLDOMAttribute *iface, - DISPID dispIdMember, REFIID riid, LCID lcid, - WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr ) +static HRESULT WINAPI domattr_Invoke(IXMLDOMAttribute *iface, DISPID dispIdMember, REFIID riid, LCID lcid, + WORD flags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT *puArgErr) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + return IDispatchEx_Invoke(&attr->dispex.IDispatchEx_iface, + dispIdMember, riid, lcid, flags, pDispParams, pVarResult, pExcepInfo, puArgErr); } -static HRESULT WINAPI domattr_get_nodeName( - IXMLDOMAttribute *iface, - BSTR* p ) +static HRESULT WINAPI domattr_get_nodeName(IXMLDOMAttribute *iface, BSTR *p) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + domattr *attr = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_nodeName(&This->node, p); + return node_get_name(attr->node, p); } -static HRESULT WINAPI domattr_get_nodeValue( - IXMLDOMAttribute *iface, - VARIANT* value) +static HRESULT WINAPI domattr_get_nodeValue(IXMLDOMAttribute *iface, VARIANT *value) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); - TRACE("(%p)->(%p)\n", This, value); + TRACE("%p, %p.\n", iface, value); - return node_get_content(&This->node, value); + return node_get_value(attr->node, value); } -static HRESULT WINAPI domattr_put_nodeValue( - IXMLDOMAttribute *iface, - VARIANT value) +static HRESULT WINAPI domattr_put_nodeValue(IXMLDOMAttribute *iface, VARIANT value) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + domattr *attr = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + TRACE("%p, %s.\n", iface, debugstr_variant(&value)); - return node_put_value_escaped(&This->node, &value); + return node_put_value(attr->node, &value); } -static HRESULT WINAPI domattr_get_nodeType( - IXMLDOMAttribute *iface, - DOMNodeType* domNodeType ) +static HRESULT WINAPI domattr_get_nodeType(IXMLDOMAttribute *iface, DOMNodeType *type) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - - TRACE("(%p)->(%p)\n", This, domNodeType); + TRACE("%p, %p.\n", iface, type); - *domNodeType = NODE_ATTRIBUTE; + *type = NODE_ATTRIBUTE; return S_OK; } -static HRESULT WINAPI domattr_get_parentNode( - IXMLDOMAttribute *iface, - IXMLDOMNode** parent ) +static HRESULT WINAPI domattr_get_parentNode(IXMLDOMAttribute *iface, IXMLDOMNode **parent) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%p)\n", This, parent); - if (!parent) return E_INVALIDARG; - *parent = NULL; - return S_FALSE; + TRACE("%p, %p\n", iface, parent); + + return return_null_node(parent); } -static HRESULT WINAPI domattr_get_childNodes( - IXMLDOMAttribute *iface, - IXMLDOMNodeList** outList) +static HRESULT WINAPI domattr_get_childNodes(IXMLDOMAttribute *iface, IXMLDOMNodeList **list) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); - TRACE("(%p)->(%p)\n", This, outList); + TRACE("%p, %p.\n", iface, list); - return node_get_child_nodes(&This->node, outList); + return node_get_child_nodes(attr->node, list); } -static HRESULT WINAPI domattr_get_firstChild( - IXMLDOMAttribute *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domattr_get_firstChild(IXMLDOMAttribute *iface, IXMLDOMNode **node) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_first_child(&This->node, domNode); + return node_get_first_child(attr->node, node); } -static HRESULT WINAPI domattr_get_lastChild( - IXMLDOMAttribute *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domattr_get_lastChild(IXMLDOMAttribute *iface, IXMLDOMNode **node) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_last_child(&This->node, domNode); + return node_get_last_child(attr->node, node); } -static HRESULT WINAPI domattr_get_previousSibling( - IXMLDOMAttribute *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domattr_get_previousSibling(IXMLDOMAttribute *iface, IXMLDOMNode **node) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI domattr_get_nextSibling( - IXMLDOMAttribute *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domattr_get_nextSibling(IXMLDOMAttribute *iface, IXMLDOMNode **node) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + TRACE("%p, %p.\n", iface, node); - TRACE("(%p)->(%p)\n", This, domNode); - - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI domattr_get_attributes( - IXMLDOMAttribute *iface, - IXMLDOMNamedNodeMap** attributeMap) +static HRESULT WINAPI domattr_get_attributes(IXMLDOMAttribute *iface, IXMLDOMNamedNodeMap **map) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - - TRACE("(%p)->(%p)\n", This, attributeMap); + TRACE("%p, %p.\n", iface, map); - return return_null_ptr((void**)attributeMap); + return return_null_ptr((void **)map); } -static HRESULT WINAPI domattr_insertBefore( - IXMLDOMAttribute *iface, - IXMLDOMNode* newNode, VARIANT refChild, - IXMLDOMNode** old_node) +static HRESULT WINAPI domattr_insertBefore(IXMLDOMAttribute *iface, IXMLDOMNode* newNode, VARIANT refChild, + IXMLDOMNode** old_node) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - DOMNodeType type; - HRESULT hr; - - FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), old_node); - - if (!newNode) return E_INVALIDARG; + domattr *attr = impl_from_IXMLDOMAttribute(iface); - hr = IXMLDOMNode_get_nodeType(newNode, &type); - if (hr != S_OK) return hr; + FIXME("%p, %p, %s, %p needs test\n", iface, newNode, debugstr_variant(&refChild), old_node); - TRACE("new node type %d\n", type); - switch (type) - { - case NODE_ATTRIBUTE: - case NODE_CDATA_SECTION: - case NODE_COMMENT: - case NODE_ELEMENT: - case NODE_PROCESSING_INSTRUCTION: - if (old_node) *old_node = NULL; - return E_FAIL; - default: - return node_insert_before(&This->node, newNode, &refChild, old_node); - } + return node_insert_before(attr->node, newNode, &refChild, old_node); } -static HRESULT WINAPI domattr_replaceChild( - IXMLDOMAttribute *iface, - IXMLDOMNode* newNode, - IXMLDOMNode* oldNode, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI domattr_replaceChild(IXMLDOMAttribute *iface, IXMLDOMNode *newNode, + IXMLDOMNode *oldNode, IXMLDOMNode **outOldNode) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); - FIXME("(%p)->(%p %p %p) needs tests\n", This, newNode, oldNode, outOldNode); + FIXME("%p, %p, %p, %p needs tests\n", iface, newNode, oldNode, outOldNode); - return node_replace_child(&This->node, newNode, oldNode, outOldNode); + return node_replace_child(attr->node, newNode, oldNode, outOldNode); } -static HRESULT WINAPI domattr_removeChild( - IXMLDOMAttribute *iface, - IXMLDOMNode *child, IXMLDOMNode **oldChild) +static HRESULT WINAPI domattr_removeChild(IXMLDOMAttribute *iface, + IXMLDOMNode *child, IXMLDOMNode **oldChild) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%p %p)\n", This, child, oldChild); - return node_remove_child(&This->node, child, oldChild); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + + TRACE("%p, %p, %p.\n", iface, child, oldChild); + + return node_remove_child(attr->node, child, oldChild); } -static HRESULT WINAPI domattr_appendChild( - IXMLDOMAttribute *iface, - IXMLDOMNode *child, IXMLDOMNode **outChild) +static HRESULT WINAPI domattr_appendChild(IXMLDOMAttribute *iface, IXMLDOMNode *child, IXMLDOMNode **outChild) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%p %p)\n", This, child, outChild); - return node_append_child(&This->node, child, outChild); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + + TRACE("%p, %p, %p.\n", iface, child, outChild); + + return node_append_child(attr->node, child, outChild); } -static HRESULT WINAPI domattr_hasChildNodes( - IXMLDOMAttribute *iface, - VARIANT_BOOL *ret) +static HRESULT WINAPI domattr_hasChildNodes(IXMLDOMAttribute *iface, VARIANT_BOOL *ret) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%p)\n", This, ret); - return node_has_childnodes(&This->node, ret); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + + TRACE("%p, %p.\n", iface, ret); + + return node_has_childnodes(attr->node, ret); } -static HRESULT WINAPI domattr_get_ownerDocument( - IXMLDOMAttribute *iface, - IXMLDOMDocument **doc) +static HRESULT WINAPI domattr_get_ownerDocument(IXMLDOMAttribute *iface, IXMLDOMDocument **doc) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%p)\n", This, doc); - return node_get_owner_doc(&This->node, doc); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + + TRACE("%p, %p.\n", iface, doc); + + return node_get_owner_document(attr->node, doc); } -static HRESULT WINAPI domattr_cloneNode( - IXMLDOMAttribute *iface, - VARIANT_BOOL deep, IXMLDOMNode** outNode) +static HRESULT WINAPI domattr_cloneNode(IXMLDOMAttribute *iface, VARIANT_BOOL deep, IXMLDOMNode **node) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%d %p)\n", This, deep, outNode); - return node_clone( &This->node, deep, outNode ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + + TRACE("%p, %d, %p.\n", iface, deep, node); + + return node_clone(attr->node, deep, node); } -static HRESULT WINAPI domattr_get_nodeTypeString( - IXMLDOMAttribute *iface, - BSTR* p) +static HRESULT WINAPI domattr_get_nodeTypeString(IXMLDOMAttribute *iface, BSTR *p) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"attribute", p); } -static HRESULT WINAPI domattr_get_text( - IXMLDOMAttribute *iface, - BSTR* p) +static HRESULT WINAPI domattr_get_text(IXMLDOMAttribute *iface, BSTR *p) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_text(&This->node, p); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_text(attr->node, p); } -static HRESULT WINAPI domattr_put_text( - IXMLDOMAttribute *iface, - BSTR p) +static HRESULT WINAPI domattr_put_text(IXMLDOMAttribute *iface, BSTR p) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - return node_put_text( &This->node, p ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(p)); + + return node_put_data(attr->node, p); } -static HRESULT WINAPI domattr_get_specified( - IXMLDOMAttribute *iface, - VARIANT_BOOL* isSpecified) +static HRESULT WINAPI domattr_get_specified(IXMLDOMAttribute *iface, VARIANT_BOOL *v) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - FIXME("(%p)->(%p) stub!\n", This, isSpecified); - *isSpecified = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domattr_get_definition( - IXMLDOMAttribute *iface, - IXMLDOMNode** definitionNode) +static HRESULT WINAPI domattr_get_definition(IXMLDOMAttribute *iface, IXMLDOMNode **node) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - FIXME("(%p)->(%p)\n", This, definitionNode); + FIXME("%p, %p\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domattr_get_nodeTypedValue( - IXMLDOMAttribute *iface, - VARIANT* value) +static HRESULT WINAPI domattr_get_nodeTypedValue(IXMLDOMAttribute *iface, VARIANT *value) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); IXMLDOMDocument *doc; HRESULT hr; - TRACE("(%p)->(%p)\n", This, value); + TRACE("%p, %p.\n", iface, value); hr = IXMLDOMAttribute_get_ownerDocument(iface, &doc); if (hr == S_OK) @@ -458,31 +375,23 @@ static HRESULT WINAPI domattr_get_nodeTypedValue( return return_null_var(value); } -static HRESULT WINAPI domattr_put_nodeTypedValue( - IXMLDOMAttribute *iface, - VARIANT typedValue) +static HRESULT WINAPI domattr_put_nodeTypedValue(IXMLDOMAttribute *iface, VARIANT v) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); + FIXME("%p, %s\n", iface, debugstr_variant(&v)); + return E_NOTIMPL; } -static HRESULT WINAPI domattr_get_dataType( - IXMLDOMAttribute *iface, - VARIANT* typename) +static HRESULT WINAPI domattr_get_dataType(IXMLDOMAttribute *iface, VARIANT *v) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%p)\n", This, typename); - return return_null_var( typename ); + TRACE("%p, %p.\n", iface, v); + + return return_null_var(v); } -static HRESULT WINAPI domattr_put_dataType( - IXMLDOMAttribute *iface, - BSTR p) +static HRESULT WINAPI domattr_put_dataType(IXMLDOMAttribute *iface, BSTR p) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - - FIXME("(%p)->(%s)\n", This, debugstr_w(p)); + FIXME("%p, %s.\n", iface, debugstr_w(p)); if(!p) return E_INVALIDARG; @@ -490,178 +399,117 @@ static HRESULT WINAPI domattr_put_dataType( return E_FAIL; } -static HRESULT WINAPI domattr_get_xml( - IXMLDOMAttribute *iface, - BSTR* p) +static HRESULT WINAPI domattr_get_xml(IXMLDOMAttribute *iface, BSTR *p) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_xml(&This->node, FALSE, p); + return node_get_xml(attr->node, p); } -static HRESULT WINAPI domattr_transformNode( - IXMLDOMAttribute *iface, - IXMLDOMNode *node, BSTR *p) +static HRESULT WINAPI domattr_transformNode(IXMLDOMAttribute *iface, IXMLDOMNode *node, BSTR *p) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%p %p)\n", This, node, p); - return node_transform_node(&This->node, node, p); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + + TRACE("%p, %p, %p.\n", iface, node, p); + + return node_transform_node(attr->node, node, p); } -static HRESULT WINAPI domattr_selectNodes( - IXMLDOMAttribute *iface, - BSTR p, IXMLDOMNodeList** outList) +static HRESULT WINAPI domattr_selectNodes(IXMLDOMAttribute *iface, BSTR p, IXMLDOMNodeList **list) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); - return node_select_nodes(&This->node, p, outList); + domattr *attr = impl_from_IXMLDOMAttribute(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), list); + + return node_select_nodes(attr->node, p, list); } -static HRESULT WINAPI domattr_selectSingleNode( - IXMLDOMAttribute *iface, - BSTR p, IXMLDOMNode** outNode) +static HRESULT WINAPI domattr_selectSingleNode(IXMLDOMAttribute *iface, BSTR p, IXMLDOMNode **node) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); - return node_select_singlenode(&This->node, p, outNode); + domattr *attr = impl_from_IXMLDOMAttribute( iface ); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), node); + + return node_select_singlenode(attr->node, p, node); } -static HRESULT WINAPI domattr_get_parsed( - IXMLDOMAttribute *iface, - VARIANT_BOOL* isParsed) +static HRESULT WINAPI domattr_get_parsed(IXMLDOMAttribute *iface, VARIANT_BOOL *v) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - FIXME("(%p)->(%p) stub!\n", This, isParsed); - *isParsed = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domattr_get_namespaceURI( - IXMLDOMAttribute *iface, - BSTR* p) +static HRESULT WINAPI domattr_get_namespaceURI(IXMLDOMAttribute *iface, BSTR *p) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - xmlNsPtr ns = This->node.node->ns; - BSTR nodename, pfx; - BOOL is6, isdefault; - HRESULT hr; + domattr *attr = impl_from_IXMLDOMAttribute(iface); - TRACE("(%p)->(%p)\n", This, p); - - if (!p) - return E_INVALIDARG; + TRACE("%p, %p.\n", iface, p); - *p = NULL; - nodename = NULL; - hr = IXMLDOMAttribute_get_nodeName(iface, &nodename); - if (FAILED(hr)) - return hr; - - pfx = NULL; - hr = IXMLDOMAttribute_get_prefix(iface, &pfx); - if (FAILED(hr)) - { - SysFreeString(nodename); - return hr; - } + return node_attribute_get_namespace_uri(attr->node, p); +} - is6 = xmldoc_version(This->node.node->doc) == MSXML6; - isdefault = !wcscmp(nodename, L"xmlns"); - if (isdefault || (pfx && !wcscmp(L"xmlns", pfx))) - { - if (is6) - *p = SysAllocString(L"http://www.w3.org/2000/xmlns/"); - else if (!ns || !isdefault) - *p = SysAllocStringLen(NULL, 0); - else - *p = SysAllocString(L"xmlns"); - } - else if (ns && ns->href) - *p = bstr_from_xmlChar(ns->href); +static HRESULT WINAPI domattr_get_prefix(IXMLDOMAttribute *iface, BSTR *prefix) +{ + domattr *attr = impl_from_IXMLDOMAttribute(iface); + struct domnode *node = attr->node; - SysFreeString(nodename); - SysFreeString(pfx); + TRACE("%p, %p.\n", iface, prefix); - TRACE("uri: %s\n", debugstr_w(*p)); + if (domdoc_version(node->owner) != MSXML6 && !wcscmp(node->name, L"xmlns")) + return return_bstr(L"xmlns", prefix); - return *p ? S_OK : S_FALSE; + return node_get_prefix(node, prefix); } -static HRESULT WINAPI domattr_get_prefix( - IXMLDOMAttribute *iface, - BSTR* prefix) +static HRESULT WINAPI domattr_get_baseName(IXMLDOMAttribute *iface, BSTR *name) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - xmlNsPtr ns = This->node.node->ns; - - TRACE("(%p)->(%p)\n", This, prefix); - - if (!prefix) return E_INVALIDARG; + domattr *attr = impl_from_IXMLDOMAttribute(iface); + struct domnode *node = attr->node; - *prefix = NULL; + TRACE("%p, %p.\n", iface, name); - if (xmldoc_version(This->node.node->doc) != MSXML6 && - xmlStrEqual(This->node.node->name, xmlns)) - *prefix = bstr_from_xmlChar(xmlns); - else if (ns && ns->prefix) - *prefix = bstr_from_xmlChar(ns->prefix); + if (domdoc_version(node->owner) != MSXML6 && !wcscmp(node->name, L"xmlns")) + return return_bstr(L"", name); - TRACE("prefix: %s\n", debugstr_w(*prefix)); - - return *prefix ? S_OK : S_FALSE; + return node_get_base_name(attr->node, name); } -static HRESULT WINAPI domattr_get_baseName( - IXMLDOMAttribute *iface, - BSTR* name) +static HRESULT WINAPI domattr_transformNodeToObject(IXMLDOMAttribute *iface, IXMLDOMNode *node, VARIANT v) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); - TRACE("(%p)->(%p)\n", This, name); - return node_get_base_name( &This->node, name ); -} + FIXME("%p, %p, %s.\n", iface, node, debugstr_variant(&v)); -static HRESULT WINAPI domattr_transformNodeToObject( - IXMLDOMAttribute *iface, - IXMLDOMNode* domNode, VARIANT var1) -{ - domattr *This = impl_from_IXMLDOMAttribute( iface ); - FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); return E_NOTIMPL; } -static HRESULT WINAPI domattr_get_name( - IXMLDOMAttribute *iface, - BSTR *p) +static HRESULT WINAPI domattr_get_name(IXMLDOMAttribute *iface, BSTR *p) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_nodeName(&This->node, p); + return node_get_name(attr->node, p); } -static HRESULT WINAPI domattr_get_value( - IXMLDOMAttribute *iface, - VARIANT *value) +static HRESULT WINAPI domattr_get_value(IXMLDOMAttribute *iface, VARIANT *value) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); - TRACE("(%p)->(%p)\n", This, value); + TRACE("%p, %p\n", iface, value); - return node_get_content(&This->node, value); + return node_get_value(attr->node, value); } -static HRESULT WINAPI domattr_put_value( - IXMLDOMAttribute *iface, - VARIANT value) +static HRESULT WINAPI domattr_put_value(IXMLDOMAttribute *iface, VARIANT value) { - domattr *This = impl_from_IXMLDOMAttribute( iface ); + domattr *attr = impl_from_IXMLDOMAttribute(iface); - TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + TRACE("%p, %s.\n", iface, debugstr_variant(&value)); - return node_put_value_escaped(&This->node, &value); + return node_put_value(attr->node, &value); } static const struct IXMLDOMAttributeVtbl domattr_vtbl = @@ -714,31 +562,36 @@ static const struct IXMLDOMAttributeVtbl domattr_vtbl = domattr_put_value }; -static const tid_t domattr_iface_tids[] = { +static const tid_t domattr_iface_tids[] = +{ IXMLDOMAttribute_tid, 0 }; -static dispex_static_data_t domattr_dispex = { +static dispex_static_data_t domattr_dispex = +{ NULL, IXMLDOMAttribute_tid, NULL, domattr_iface_tids }; -IUnknown* create_attribute( xmlNodePtr attribute, BOOL floating ) +HRESULT create_attribute(struct domnode *node, IUnknown **obj) { - domattr *This; + domattr *object; + + *obj = NULL; - This = malloc(sizeof(*This)); - if ( !This ) - return NULL; + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; - This->IXMLDOMAttribute_iface.lpVtbl = &domattr_vtbl; - This->ref = 1; - This->floating = floating; + object->IXMLDOMAttribute_iface.lpVtbl = &domattr_vtbl; + object->refcount = 1; + object->node = domnode_addref(node); - init_xmlnode(&This->node, attribute, (IXMLDOMNode*)&This->IXMLDOMAttribute_iface, &domattr_dispex); + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMAttribute_iface, &domattr_dispex); - return (IUnknown*)&This->IXMLDOMAttribute_iface; + *obj = (IUnknown *)&object->IXMLDOMAttribute_iface; + + return S_OK; } diff --git a/dlls/msxml3/cdata.c b/dlls/msxml3/cdata.c index cab35e6c5c8..8b5fd378700 100644 --- a/dlls/msxml3/cdata.c +++ b/dlls/msxml3/cdata.c @@ -21,8 +21,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> #include "windef.h" #include "winbase.h" @@ -38,9 +36,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); typedef struct { - xmlnode node; + DispatchEx dispex; IXMLDOMCDATASection IXMLDOMCDATASection_iface; - LONG ref; + LONG refcount; + struct domnode *node; } domcdata; static const tid_t domcdata_se_tids[] = { @@ -54,13 +53,11 @@ static inline domcdata *impl_from_IXMLDOMCDATASection( IXMLDOMCDATASection *ifac return CONTAINING_RECORD(iface, domcdata, IXMLDOMCDATASection_iface); } -static HRESULT WINAPI domcdata_QueryInterface( - IXMLDOMCDATASection *iface, - REFIID riid, - void** ppvObject ) +static HRESULT WINAPI domcdata_QueryInterface(IXMLDOMCDATASection *iface, REFIID riid, void **obj) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); if ( IsEqualGUID( riid, &IID_IXMLDOMCDATASection ) || IsEqualGUID( riid, &IID_IXMLDOMCharacterData) || @@ -68,20 +65,24 @@ static HRESULT WINAPI domcdata_QueryInterface( IsEqualGUID( riid, &IID_IDispatch ) || IsEqualGUID( riid, &IID_IUnknown ) ) { - *ppvObject = iface; + *obj = iface; + } + else if (dispex_query_interface(&cdata->dispex, riid, obj)) + { + return *obj ? S_OK : E_NOINTERFACE; } - else if(node_query_interface(&This->node, riid, ppvObject)) + else if (node_query_interface(cdata->node, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } - else if(IsEqualGUID( riid, &IID_ISupportErrorInfo )) + else if (IsEqualGUID(riid, &IID_ISupportErrorInfo)) { - return node_create_supporterrorinfo(domcdata_se_tids, ppvObject); + return node_create_supporterrorinfo(domcdata_se_tids, obj); } else { - TRACE("Unsupported interface %s\n", debugstr_guid(riid)); - *ppvObject = NULL; + WARN("Unsupported interface %s\n", debugstr_guid(riid)); + *obj = NULL; return E_NOINTERFACE; } @@ -92,7 +93,7 @@ static HRESULT WINAPI domcdata_QueryInterface( static ULONG WINAPI domcdata_AddRef(IXMLDOMCDATASection *iface) { domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); - ULONG ref = InterlockedIncrement(&cdata->ref); + ULONG ref = InterlockedIncrement(&cdata->refcount); TRACE("%p, refcount %lu.\n", iface, ref); return ref; } @@ -100,460 +101,368 @@ static ULONG WINAPI domcdata_AddRef(IXMLDOMCDATASection *iface) static ULONG WINAPI domcdata_Release(IXMLDOMCDATASection *iface) { domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); - ULONG ref = InterlockedDecrement(&cdata->ref); + ULONG ref = InterlockedDecrement(&cdata->refcount); TRACE("%p, refcount %lu.\n", iface, ref); if (!ref) { - destroy_xmlnode(&cdata->node); + domnode_release(cdata->node); free(cdata); } return ref; } -static HRESULT WINAPI domcdata_GetTypeInfoCount( - IXMLDOMCDATASection *iface, - UINT* pctinfo ) +static HRESULT WINAPI domcdata_GetTypeInfoCount(IXMLDOMCDATASection *iface, UINT *count) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + return IDispatchEx_GetTypeInfoCount(&cdata->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI domcdata_GetTypeInfo( - IXMLDOMCDATASection *iface, - UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI domcdata_GetTypeInfo(IXMLDOMCDATASection *iface, UINT index, LCID lcid, ITypeInfo **ti) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + return IDispatchEx_GetTypeInfo(&cdata->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI domcdata_GetIDsOfNames( - IXMLDOMCDATASection *iface, - REFIID riid, LPOLESTR* rgszNames, - UINT cNames, LCID lcid, DISPID* rgDispId ) +static HRESULT WINAPI domcdata_GetIDsOfNames(IXMLDOMCDATASection *iface, REFIID riid, LPOLESTR* rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, - riid, rgszNames, cNames, lcid, rgDispId); + domcdata *cdata = impl_from_IXMLDOMCDATASection( iface ); + return IDispatchEx_GetIDsOfNames(&cdata->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); } -static HRESULT WINAPI domcdata_Invoke( - IXMLDOMCDATASection *iface, - DISPID dispIdMember, REFIID riid, LCID lcid, - WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr ) +static HRESULT WINAPI domcdata_Invoke(IXMLDOMCDATASection *iface, DISPID dispIdMember, REFIID riid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *puArgErr) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + return IDispatchEx_Invoke(&cdata->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, flags, + params, result, ei, puArgErr); } -static HRESULT WINAPI domcdata_get_nodeName( - IXMLDOMCDATASection *iface, - BSTR* p ) +static HRESULT WINAPI domcdata_get_nodeName(IXMLDOMCDATASection *iface, BSTR *p) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"#cdata-section", p); } -static HRESULT WINAPI domcdata_get_nodeValue( - IXMLDOMCDATASection *iface, - VARIANT* value) +static HRESULT WINAPI domcdata_get_nodeValue(IXMLDOMCDATASection *iface, VARIANT *value) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); - TRACE("(%p)->(%p)\n", This, value); + TRACE("%p, %p.\n", iface, value); - return node_get_content(&This->node, value); + return node_get_value(cdata->node, value); } -static HRESULT WINAPI domcdata_put_nodeValue( - IXMLDOMCDATASection *iface, - VARIANT value) +static HRESULT WINAPI domcdata_put_nodeValue(IXMLDOMCDATASection *iface, VARIANT value) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + domcdata *cdata = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + TRACE("%p, %s.\n", iface, debugstr_variant(&value)); - return node_put_value(&This->node, &value); + return node_put_value(cdata->node, &value); } -static HRESULT WINAPI domcdata_get_nodeType( - IXMLDOMCDATASection *iface, - DOMNodeType* domNodeType ) +static HRESULT WINAPI domcdata_get_nodeType(IXMLDOMCDATASection *iface, DOMNodeType *type) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + TRACE("%p, %p.\n", iface, type); - TRACE("(%p)->(%p)\n", This, domNodeType); - - *domNodeType = NODE_CDATA_SECTION; + *type = NODE_CDATA_SECTION; return S_OK; } -static HRESULT WINAPI domcdata_get_parentNode( - IXMLDOMCDATASection *iface, - IXMLDOMNode** parent ) +static HRESULT WINAPI domcdata_get_parentNode(IXMLDOMCDATASection *iface, IXMLDOMNode **parent) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); - TRACE("(%p)->(%p)\n", This, parent); + TRACE("%p, %p.\n", iface, parent); - return node_get_parent(&This->node, parent); + return node_get_parent(cdata->node, parent); } -static HRESULT WINAPI domcdata_get_childNodes( - IXMLDOMCDATASection *iface, - IXMLDOMNodeList** outList) +static HRESULT WINAPI domcdata_get_childNodes(IXMLDOMCDATASection *iface, IXMLDOMNodeList **list) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); - TRACE("(%p)->(%p)\n", This, outList); + TRACE("%p, %p.\n", iface, list); - return node_get_child_nodes(&This->node, outList); + return node_get_child_nodes(cdata->node, list); } -static HRESULT WINAPI domcdata_get_firstChild( - IXMLDOMCDATASection *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domcdata_get_firstChild(IXMLDOMCDATASection *iface, IXMLDOMNode **node) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI domcdata_get_lastChild( - IXMLDOMCDATASection *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domcdata_get_lastChild(IXMLDOMCDATASection *iface, IXMLDOMNode **node) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI domcdata_get_previousSibling( - IXMLDOMCDATASection *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domcdata_get_previousSibling(IXMLDOMCDATASection *iface, IXMLDOMNode **node) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_previous_sibling(&This->node, domNode); + return node_get_previous_sibling(cdata->node, node); } -static HRESULT WINAPI domcdata_get_nextSibling( - IXMLDOMCDATASection *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domcdata_get_nextSibling(IXMLDOMCDATASection *iface, IXMLDOMNode **node) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_next_sibling(&This->node, domNode); + return node_get_next_sibling(cdata->node, node); } -static HRESULT WINAPI domcdata_get_attributes( - IXMLDOMCDATASection *iface, - IXMLDOMNamedNodeMap** attributeMap) +static HRESULT WINAPI domcdata_get_attributes(IXMLDOMCDATASection *iface, IXMLDOMNamedNodeMap **map) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - - TRACE("(%p)->(%p)\n", This, attributeMap); + TRACE("%p, %p.\n", iface, map); - return return_null_ptr((void**)attributeMap); + return return_null_ptr((void **)map); } -static HRESULT WINAPI domcdata_insertBefore( - IXMLDOMCDATASection *iface, - IXMLDOMNode* newNode, VARIANT refChild, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI domcdata_insertBefore(IXMLDOMCDATASection *iface, IXMLDOMNode *node, + VARIANT refChild, IXMLDOMNode **oldnode) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), outOldNode); - if (outOldNode) *outOldNode = NULL; + TRACE("%p, %p, %s, %p.\n", iface, node, debugstr_variant(&refChild), oldnode); + + if (oldnode) *oldnode = NULL; return E_FAIL; } -static HRESULT WINAPI domcdata_replaceChild( - IXMLDOMCDATASection *iface, - IXMLDOMNode* newNode, - IXMLDOMNode* oldNode, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI domcdata_replaceChild(IXMLDOMCDATASection *iface, IXMLDOMNode *node, + IXMLDOMNode *oldnode, IXMLDOMNode **out_oldnode) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p %p %p)\n", This, newNode, oldNode, outOldNode); - if (outOldNode) *outOldNode = NULL; + TRACE("%p, %p, %p, %p.\n", iface, node, oldnode, out_oldnode); + + if (out_oldnode) *out_oldnode = NULL; return E_FAIL; } -static HRESULT WINAPI domcdata_removeChild( - IXMLDOMCDATASection *iface, - IXMLDOMNode *child, IXMLDOMNode **oldChild) +static HRESULT WINAPI domcdata_removeChild(IXMLDOMCDATASection *iface, IXMLDOMNode *child, IXMLDOMNode **oldChild) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p %p)\n", This, child, oldChild); + TRACE("%p, %p, %p.\n", iface, child, oldChild); + if (oldChild) *oldChild = NULL; return E_FAIL; } -static HRESULT WINAPI domcdata_appendChild( - IXMLDOMCDATASection *iface, - IXMLDOMNode *child, IXMLDOMNode **outChild) +static HRESULT WINAPI domcdata_appendChild(IXMLDOMCDATASection *iface, IXMLDOMNode *child, IXMLDOMNode **outChild) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p %p)\n", This, child, outChild); + TRACE("%p, %p, %p.\n", iface, child, outChild); + if (outChild) *outChild = NULL; return E_FAIL; } -static HRESULT WINAPI domcdata_hasChildNodes( - IXMLDOMCDATASection *iface, - VARIANT_BOOL *ret) +static HRESULT WINAPI domcdata_hasChildNodes(IXMLDOMCDATASection *iface, VARIANT_BOOL *ret) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p)\n", This, ret); + TRACE("%p, %p.\n", iface, ret); + return return_var_false(ret); } -static HRESULT WINAPI domcdata_get_ownerDocument( - IXMLDOMCDATASection *iface, - IXMLDOMDocument **doc) +static HRESULT WINAPI domcdata_get_ownerDocument(IXMLDOMCDATASection *iface, IXMLDOMDocument **doc) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p)\n", This, doc); - return node_get_owner_doc(&This->node, doc); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + + TRACE("%p, %p.\n", iface, doc); + + return node_get_owner_document(cdata->node, doc); } -static HRESULT WINAPI domcdata_cloneNode( - IXMLDOMCDATASection *iface, - VARIANT_BOOL deep, IXMLDOMNode** outNode) +static HRESULT WINAPI domcdata_cloneNode(IXMLDOMCDATASection *iface, VARIANT_BOOL deep, IXMLDOMNode **node) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%d %p)\n", This, deep, outNode); - return node_clone( &This->node, deep, outNode ); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + + TRACE("%p, %d, %p.\n", iface, deep, node); + + return node_clone(cdata->node, deep, node); } -static HRESULT WINAPI domcdata_get_nodeTypeString( - IXMLDOMCDATASection *iface, - BSTR* p) +static HRESULT WINAPI domcdata_get_nodeTypeString(IXMLDOMCDATASection *iface, BSTR *p) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"cdatasection", p); } -static HRESULT WINAPI domcdata_get_text( - IXMLDOMCDATASection *iface, - BSTR* p) +static HRESULT WINAPI domcdata_get_text(IXMLDOMCDATASection *iface, BSTR *p) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_text(&This->node, p); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_text(cdata->node, p); } -static HRESULT WINAPI domcdata_put_text( - IXMLDOMCDATASection *iface, - BSTR p) +static HRESULT WINAPI domcdata_put_text(IXMLDOMCDATASection *iface, BSTR p) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - return node_put_text( &This->node, p ); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(p)); + + return node_put_data(cdata->node, p); } -static HRESULT WINAPI domcdata_get_specified( - IXMLDOMCDATASection *iface, - VARIANT_BOOL* isSpecified) +static HRESULT WINAPI domcdata_get_specified(IXMLDOMCDATASection *iface, VARIANT_BOOL *v) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - FIXME("(%p)->(%p) stub!\n", This, isSpecified); - *isSpecified = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domcdata_get_definition( - IXMLDOMCDATASection *iface, - IXMLDOMNode** definitionNode) +static HRESULT WINAPI domcdata_get_definition(IXMLDOMCDATASection *iface, IXMLDOMNode **node) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - FIXME("(%p)->(%p)\n", This, definitionNode); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domcdata_get_nodeTypedValue( - IXMLDOMCDATASection *iface, - VARIANT* v) +static HRESULT WINAPI domcdata_get_nodeTypedValue(IXMLDOMCDATASection *iface, VARIANT *v) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p)\n", This, v); - return node_get_content(&This->node, v); + domcdata *cdata = impl_from_IXMLDOMCDATASection( iface ); + + TRACE("%p, %p.\n", iface, v); + + return node_get_value(cdata->node, v); } -static HRESULT WINAPI domcdata_put_nodeTypedValue( - IXMLDOMCDATASection *iface, - VARIANT typedValue) +static HRESULT WINAPI domcdata_put_nodeTypedValue(IXMLDOMCDATASection *iface, VARIANT v) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); + FIXME("%p, %s.\n", iface, debugstr_variant(&v)); + return E_NOTIMPL; } -static HRESULT WINAPI domcdata_get_dataType( - IXMLDOMCDATASection *iface, - VARIANT* typename) +static HRESULT WINAPI domcdata_get_dataType(IXMLDOMCDATASection *iface, VARIANT *v) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p)\n", This, typename); - return return_null_var( typename ); + TRACE("%p, %p.\n", iface, v); + + return return_null_var(v); } -static HRESULT WINAPI domcdata_put_dataType( - IXMLDOMCDATASection *iface, - BSTR p) +static HRESULT WINAPI domcdata_put_dataType(IXMLDOMCDATASection *iface, BSTR p) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + TRACE("%p, %s.\n", iface, debugstr_w(p)); - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - - if(!p) + if (!p) return E_INVALIDARG; return E_FAIL; } -static HRESULT WINAPI domcdata_get_xml( - IXMLDOMCDATASection *iface, - BSTR* p) +static HRESULT WINAPI domcdata_get_xml(IXMLDOMCDATASection *iface, BSTR *p) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_xml(&This->node, FALSE, p); + return node_get_xml(cdata->node, p); } -static HRESULT WINAPI domcdata_transformNode( - IXMLDOMCDATASection *iface, - IXMLDOMNode *node, BSTR *p) +static HRESULT WINAPI domcdata_transformNode(IXMLDOMCDATASection *iface, IXMLDOMNode *node, BSTR *p) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p %p)\n", This, node, p); - return node_transform_node(&This->node, node, p); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + + TRACE("%p, %p, %p.\n", iface, node, p); + + return node_transform_node(cdata->node, node, p); } -static HRESULT WINAPI domcdata_selectNodes( - IXMLDOMCDATASection *iface, - BSTR p, IXMLDOMNodeList** outList) +static HRESULT WINAPI domcdata_selectNodes(IXMLDOMCDATASection *iface, BSTR p, IXMLDOMNodeList **list) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); - return node_select_nodes(&This->node, p, outList); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), list); + + return node_select_nodes(cdata->node, p, list); } -static HRESULT WINAPI domcdata_selectSingleNode( - IXMLDOMCDATASection *iface, - BSTR p, IXMLDOMNode** outNode) +static HRESULT WINAPI domcdata_selectSingleNode(IXMLDOMCDATASection *iface, BSTR p, IXMLDOMNode **node) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); - return node_select_singlenode(&This->node, p, outNode); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), node); + + return node_select_singlenode(cdata->node, p, node); } -static HRESULT WINAPI domcdata_get_parsed( - IXMLDOMCDATASection *iface, - VARIANT_BOOL* isParsed) +static HRESULT WINAPI domcdata_get_parsed(IXMLDOMCDATASection *iface, VARIANT_BOOL *v) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - FIXME("(%p)->(%p) stub!\n", This, isParsed); - *isParsed = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domcdata_get_namespaceURI( - IXMLDOMCDATASection *iface, - BSTR* p) +static HRESULT WINAPI domcdata_get_namespaceURI(IXMLDOMCDATASection *iface, BSTR *p) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_namespaceURI(&This->node, p); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_namespaceURI(cdata->node, p); } -static HRESULT WINAPI domcdata_get_prefix( - IXMLDOMCDATASection *iface, - BSTR* prefix) +static HRESULT WINAPI domcdata_get_prefix(IXMLDOMCDATASection *iface, BSTR *prefix) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%p)\n", This, prefix); - return return_null_bstr( prefix ); + TRACE("%p, %p.\n", iface, prefix); + + return return_null_bstr(prefix); } -static HRESULT WINAPI domcdata_get_baseName( - IXMLDOMCDATASection *iface, - BSTR* name) +static HRESULT WINAPI domcdata_get_baseName(IXMLDOMCDATASection *iface, BSTR *name) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - FIXME("(%p)->(%p): needs test\n", This, name); - return return_null_bstr( name ); + FIXME("%p, %p: needs test\n", iface, name); + + return return_null_bstr(name); } -static HRESULT WINAPI domcdata_transformNodeToObject( - IXMLDOMCDATASection *iface, - IXMLDOMNode* domNode, VARIANT var1) +static HRESULT WINAPI domcdata_transformNodeToObject(IXMLDOMCDATASection *iface, IXMLDOMNode *node, VARIANT var1) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); + FIXME("%p, %p, %s.\n", iface, node, debugstr_variant(&var1)); + return E_NOTIMPL; } -static HRESULT WINAPI domcdata_get_data( - IXMLDOMCDATASection *iface, - BSTR *p) +static HRESULT WINAPI domcdata_get_data(IXMLDOMCDATASection *iface, BSTR *p) { - HRESULT hr; - VARIANT vRet; - - if(!p) - return E_INVALIDARG; + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); - hr = IXMLDOMCDATASection_get_nodeValue( iface, &vRet ); - if(hr == S_OK) - { - *p = V_BSTR(&vRet); - } + TRACE("%p, %p.\n", iface, p); - return hr; + return node_get_data(cdata->node, p); } -static HRESULT WINAPI domcdata_put_data( - IXMLDOMCDATASection *iface, - BSTR data) +static HRESULT WINAPI domcdata_put_data(IXMLDOMCDATASection *iface, BSTR data) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_w(data)); - return node_set_content(&This->node, data); + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(data)); + + return node_put_data(cdata->node, data); } static HRESULT WINAPI domcdata_get_length( IXMLDOMCDATASection *iface, LONG *len) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); HRESULT hr; BSTR data; - TRACE("(%p)->(%p)\n", This, len); + TRACE("%p, %p.\n", iface, len); if(!len) return E_INVALIDARG; @@ -608,37 +517,13 @@ static HRESULT WINAPI domcdata_substringData( return hr; } -static HRESULT WINAPI domcdata_appendData( - IXMLDOMCDATASection *iface, - BSTR p) +static HRESULT WINAPI domcdata_appendData(IXMLDOMCDATASection *iface, BSTR p) { - domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - HRESULT hr; - BSTR data; - LONG p_len; - - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - - /* Nothing to do if NULL or an Empty string passed in. */ - if((p_len = SysStringLen(p)) == 0) return S_OK; - - hr = IXMLDOMCDATASection_get_data(iface, &data); - if(hr == S_OK) - { - LONG len = SysStringLen(data); - BSTR str = SysAllocStringLen(NULL, p_len + len); - - memcpy(str, data, len*sizeof(WCHAR)); - memcpy(&str[len], p, p_len*sizeof(WCHAR)); - str[len+p_len] = 0; + domcdata *cdata = impl_from_IXMLDOMCDATASection(iface); - hr = IXMLDOMCDATASection_put_data(iface, str); + TRACE("%p, %s.\n", iface, debugstr_w(p)); - SysFreeString(str); - SysFreeString(data); - } - - return hr; + return node_append_data(cdata->node, p); } static HRESULT WINAPI domcdata_insertData( @@ -855,30 +740,36 @@ static const struct IXMLDOMCDATASectionVtbl domcdata_vtbl = domcdata_splitText }; -static const tid_t domcdata_iface_tids[] = { +static const tid_t domcdata_iface_tids[] = +{ IXMLDOMCDATASection_tid, 0 }; -static dispex_static_data_t domcdata_dispex = { +static dispex_static_data_t domcdata_dispex = +{ NULL, IXMLDOMCDATASection_tid, NULL, domcdata_iface_tids }; -IUnknown* create_cdata( xmlNodePtr text ) +HRESULT create_cdata(struct domnode *node, IUnknown **obj) { - domcdata *This; + domcdata *object; + + *obj = NULL; - This = malloc(sizeof(*This)); - if ( !This ) - return NULL; + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; - This->IXMLDOMCDATASection_iface.lpVtbl = &domcdata_vtbl; - This->ref = 1; + object->IXMLDOMCDATASection_iface.lpVtbl = &domcdata_vtbl; + object->refcount = 1; + object->node = domnode_addref(node); - init_xmlnode(&This->node, text, (IXMLDOMNode*)&This->IXMLDOMCDATASection_iface, &domcdata_dispex); + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMCDATASection_iface, &domcdata_dispex); - return (IUnknown*)&This->IXMLDOMCDATASection_iface; + *obj = (IUnknown *)&object->IXMLDOMCDATASection_iface; + + return S_OK; } diff --git a/dlls/msxml3/comment.c b/dlls/msxml3/comment.c index ba0a4282174..fe53ac57e05 100644 --- a/dlls/msxml3/comment.c +++ b/dlls/msxml3/comment.c @@ -21,8 +21,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> #include "windef.h" #include "winbase.h" @@ -38,50 +36,54 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); typedef struct _domcomment { - xmlnode node; + DispatchEx dispex; IXMLDOMComment IXMLDOMComment_iface; - LONG ref; + LONG refcount; + struct domnode *node; } domcomment; -static const tid_t domcomment_se_tids[] = { +static const tid_t domcomment_se_tids[] = +{ IXMLDOMNode_tid, IXMLDOMComment_tid, NULL_tid }; -static inline domcomment *impl_from_IXMLDOMComment( IXMLDOMComment *iface ) +static inline domcomment *impl_from_IXMLDOMComment(IXMLDOMComment *iface) { return CONTAINING_RECORD(iface, domcomment, IXMLDOMComment_iface); } -static HRESULT WINAPI domcomment_QueryInterface( - IXMLDOMComment *iface, - REFIID riid, - void** ppvObject ) +static HRESULT WINAPI domcomment_QueryInterface(IXMLDOMComment *iface, REFIID riid, void **obj) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + domcomment *comment = impl_from_IXMLDOMComment(iface); - if ( IsEqualGUID( riid, &IID_IXMLDOMComment ) || - IsEqualGUID( riid, &IID_IXMLDOMCharacterData) || - IsEqualGUID( riid, &IID_IXMLDOMNode ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IUnknown ) ) + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + if (IsEqualGUID(riid, &IID_IXMLDOMComment) || + IsEqualGUID(riid, &IID_IXMLDOMCharacterData) || + IsEqualGUID(riid, &IID_IXMLDOMNode) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IUnknown)) + { + *obj = iface; + } + else if (dispex_query_interface(&comment->dispex, riid, obj)) { - *ppvObject = iface; + return *obj ? S_OK : E_NOINTERFACE; } - else if(node_query_interface(&This->node, riid, ppvObject)) + else if (node_query_interface(comment->node, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } - else if(IsEqualGUID( riid, &IID_ISupportErrorInfo )) + else if (IsEqualGUID(riid, &IID_ISupportErrorInfo)) { - return node_create_supporterrorinfo(domcomment_se_tids, ppvObject); + return node_create_supporterrorinfo(domcomment_se_tids, obj); } else { TRACE("Unsupported interface %s\n", debugstr_guid(riid)); - *ppvObject = NULL; + *obj = NULL; return E_NOINTERFACE; } @@ -92,471 +94,381 @@ static HRESULT WINAPI domcomment_QueryInterface( static ULONG WINAPI domcomment_AddRef(IXMLDOMComment *iface) { domcomment *comment = impl_from_IXMLDOMComment(iface); - ULONG ref = InterlockedIncrement(&comment->ref); - TRACE("%p, refcount %lu.\n", iface, ref); - return ref; + ULONG refcount = InterlockedIncrement(&comment->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); + + return refcount; } static ULONG WINAPI domcomment_Release(IXMLDOMComment *iface) { domcomment *comment = impl_from_IXMLDOMComment(iface); - ULONG ref = InterlockedDecrement(&comment->ref); + ULONG refcount = InterlockedDecrement(&comment->refcount); - TRACE("%p, refcount %lu.\n", iface, ref); + TRACE("%p, refcount %lu.\n", iface, refcount); - if (!ref) + if (!refcount) { - destroy_xmlnode(&comment->node); + domnode_release(comment->node); free(comment); } - return ref; + return refcount; } -static HRESULT WINAPI domcomment_GetTypeInfoCount( - IXMLDOMComment *iface, - UINT* pctinfo ) +static HRESULT WINAPI domcomment_GetTypeInfoCount(IXMLDOMComment *iface, UINT *count) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); + domcomment *comment = impl_from_IXMLDOMComment(iface); + return IDispatchEx_GetTypeInfoCount(&comment->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI domcomment_GetTypeInfo( - IXMLDOMComment *iface, - UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI domcomment_GetTypeInfo(IXMLDOMComment *iface, UINT index, LCID lcid, ITypeInfo **ti) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + domcomment *comment = impl_from_IXMLDOMComment(iface); + return IDispatchEx_GetTypeInfo(&comment->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI domcomment_GetIDsOfNames( - IXMLDOMComment *iface, - REFIID riid, LPOLESTR* rgszNames, - UINT cNames, LCID lcid, DISPID* rgDispId ) +static HRESULT WINAPI domcomment_GetIDsOfNames(IXMLDOMComment *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, + domcomment *comment = impl_from_IXMLDOMComment(iface); + return IDispatchEx_GetIDsOfNames(&comment->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); } -static HRESULT WINAPI domcomment_Invoke( - IXMLDOMComment *iface, - DISPID dispIdMember, REFIID riid, LCID lcid, - WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr ) +static HRESULT WINAPI domcomment_Invoke(IXMLDOMComment *iface, DISPID dispIdMember, REFIID riid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *puArgErr) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + domcomment *comment = impl_from_IXMLDOMComment(iface); + return IDispatchEx_Invoke(&comment->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, flags, + params, result, ei, puArgErr); } -static HRESULT WINAPI domcomment_get_nodeName( - IXMLDOMComment *iface, - BSTR* p ) +static HRESULT WINAPI domcomment_get_nodeName(IXMLDOMComment *iface, BSTR *p) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"#comment", p); } -static HRESULT WINAPI domcomment_get_nodeValue( - IXMLDOMComment *iface, - VARIANT* value) +static HRESULT WINAPI domcomment_get_nodeValue(IXMLDOMComment *iface, VARIANT *value) { - domcomment *This = impl_from_IXMLDOMComment( iface ); + domcomment *comment = impl_from_IXMLDOMComment(iface); - TRACE("(%p)->(%p)\n", This, value); + TRACE("%p, %p.\n", iface, value); - return node_get_content(&This->node, value); + return node_get_value(comment->node, value); } -static HRESULT WINAPI domcomment_put_nodeValue( - IXMLDOMComment *iface, - VARIANT value) +static HRESULT WINAPI domcomment_put_nodeValue(IXMLDOMComment *iface, VARIANT value) { - domcomment *This = impl_from_IXMLDOMComment( iface ); + domcomment *comment = impl_from_IXMLDOMComment(iface); - TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + TRACE("%p, %s.\n", iface, debugstr_variant(&value)); - return node_put_value(&This->node, &value); + return node_put_value(comment->node, &value); } -static HRESULT WINAPI domcomment_get_nodeType( - IXMLDOMComment *iface, - DOMNodeType* domNodeType ) +static HRESULT WINAPI domcomment_get_nodeType(IXMLDOMComment *iface, DOMNodeType *type) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - - TRACE("(%p)->(%p)\n", This, domNodeType); + TRACE("%p, %p.\n", iface, type); - *domNodeType = NODE_COMMENT; + *type = NODE_COMMENT; return S_OK; } -static HRESULT WINAPI domcomment_get_parentNode( - IXMLDOMComment *iface, - IXMLDOMNode** parent ) +static HRESULT WINAPI domcomment_get_parentNode(IXMLDOMComment *iface, IXMLDOMNode **parent) { - domcomment *This = impl_from_IXMLDOMComment( iface ); + domcomment *comment = impl_from_IXMLDOMComment(iface); - TRACE("(%p)->(%p)\n", This, parent); + TRACE("%p, %p.\n", iface, parent); - return node_get_parent(&This->node, parent); + return node_get_parent(comment->node, parent); } -static HRESULT WINAPI domcomment_get_childNodes( - IXMLDOMComment *iface, - IXMLDOMNodeList** outList) +static HRESULT WINAPI domcomment_get_childNodes(IXMLDOMComment *iface, IXMLDOMNodeList **list) { - domcomment *This = impl_from_IXMLDOMComment( iface ); + domcomment *comment = impl_from_IXMLDOMComment(iface); - TRACE("(%p)->(%p)\n", This, outList); + TRACE("%p, %p.\n", iface, list); - return node_get_child_nodes(&This->node, outList); + return node_get_child_nodes(comment->node, list); } -static HRESULT WINAPI domcomment_get_firstChild( - IXMLDOMComment *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domcomment_get_firstChild(IXMLDOMComment *iface, IXMLDOMNode **node) { - domcomment *This = impl_from_IXMLDOMComment( iface ); + TRACE("%p, %p.\n", iface, node); - TRACE("(%p)->(%p)\n", This, domNode); - - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI domcomment_get_lastChild( - IXMLDOMComment *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domcomment_get_lastChild(IXMLDOMComment *iface, IXMLDOMNode **node) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI domcomment_get_previousSibling( - IXMLDOMComment *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domcomment_get_previousSibling(IXMLDOMComment *iface, IXMLDOMNode **node) { - domcomment *This = impl_from_IXMLDOMComment( iface ); + domcomment *comment = impl_from_IXMLDOMComment(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_previous_sibling(&This->node, domNode); + return node_get_previous_sibling(comment->node, node); } -static HRESULT WINAPI domcomment_get_nextSibling( - IXMLDOMComment *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domcomment_get_nextSibling(IXMLDOMComment *iface, IXMLDOMNode **node) { - domcomment *This = impl_from_IXMLDOMComment( iface ); + domcomment *comment = impl_from_IXMLDOMComment(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_next_sibling(&This->node, domNode); + return node_get_next_sibling(comment->node, node); } -static HRESULT WINAPI domcomment_get_attributes( - IXMLDOMComment *iface, - IXMLDOMNamedNodeMap** attributeMap) +static HRESULT WINAPI domcomment_get_attributes(IXMLDOMComment *iface, IXMLDOMNamedNodeMap **map) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - - TRACE("(%p)->(%p)\n", This, attributeMap); + TRACE("%p, %p.\n", iface, map); - return return_null_ptr((void**)attributeMap); + return return_null_ptr((void **)map); } -static HRESULT WINAPI domcomment_insertBefore( - IXMLDOMComment *iface, - IXMLDOMNode* newNode, VARIANT refChild, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI domcomment_insertBefore(IXMLDOMComment *iface, IXMLDOMNode *newNode, + VARIANT refChild, IXMLDOMNode **outOldNode) { - domcomment *This = impl_from_IXMLDOMComment( iface ); + domcomment *comment = impl_from_IXMLDOMComment(iface); - FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode); + FIXME("%p, %p, %s, %p needs test\n", iface, newNode, debugstr_variant(&refChild), outOldNode); - return node_insert_before(&This->node, newNode, &refChild, outOldNode); + return node_insert_before(comment->node, newNode, &refChild, outOldNode); } -static HRESULT WINAPI domcomment_replaceChild( - IXMLDOMComment *iface, - IXMLDOMNode* newNode, - IXMLDOMNode* oldNode, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI domcomment_replaceChild(IXMLDOMComment *iface, IXMLDOMNode *newNode, + IXMLDOMNode *oldNode, IXMLDOMNode **outOldNode) { - domcomment *This = impl_from_IXMLDOMComment( iface ); + domcomment *comment = impl_from_IXMLDOMComment(iface); - FIXME("(%p)->(%p %p %p) needs tests\n", This, newNode, oldNode, outOldNode); + FIXME("%p, %p, %p, %p needs tests\n", iface, newNode, oldNode, outOldNode); - return node_replace_child(&This->node, newNode, oldNode, outOldNode); + return node_replace_child(comment->node, newNode, oldNode, outOldNode); } -static HRESULT WINAPI domcomment_removeChild( - IXMLDOMComment *iface, - IXMLDOMNode *child, IXMLDOMNode **oldChild) +static HRESULT WINAPI domcomment_removeChild(IXMLDOMComment *iface, IXMLDOMNode *child, IXMLDOMNode **oldChild) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%p %p)\n", This, child, oldChild); - return node_remove_child(&This->node, child, oldChild); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %p, %p.\n", iface, child, oldChild); + + return node_remove_child(comment->node, child, oldChild); } -static HRESULT WINAPI domcomment_appendChild( - IXMLDOMComment *iface, - IXMLDOMNode *child, IXMLDOMNode **outChild) +static HRESULT WINAPI domcomment_appendChild(IXMLDOMComment *iface, IXMLDOMNode *child, IXMLDOMNode **outChild) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%p %p)\n", This, child, outChild); - return node_append_child(&This->node, child, outChild); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %p, %p.\n", iface, child, outChild); + + return node_append_child(comment->node, child, outChild); } -static HRESULT WINAPI domcomment_hasChildNodes( - IXMLDOMComment *iface, - VARIANT_BOOL *ret) +static HRESULT WINAPI domcomment_hasChildNodes(IXMLDOMComment *iface, VARIANT_BOOL *ret) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%p)\n", This, ret); + TRACE("%p %p.\n", iface, ret); + return return_var_false(ret); } -static HRESULT WINAPI domcomment_get_ownerDocument( - IXMLDOMComment *iface, - IXMLDOMDocument **doc) +static HRESULT WINAPI domcomment_get_ownerDocument(IXMLDOMComment *iface, IXMLDOMDocument **doc) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%p)\n", This, doc); - return node_get_owner_doc(&This->node, doc); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %p.\n", iface, doc); + + return node_get_owner_document(comment->node, doc); } -static HRESULT WINAPI domcomment_cloneNode( - IXMLDOMComment *iface, - VARIANT_BOOL deep, IXMLDOMNode** outNode) +static HRESULT WINAPI domcomment_cloneNode(IXMLDOMComment *iface, VARIANT_BOOL deep, IXMLDOMNode **node) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%d %p)\n", This, deep, outNode); - return node_clone( &This->node, deep, outNode ); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %d, %p.\n", iface, deep, node); + + return node_clone(comment->node, deep, node); } -static HRESULT WINAPI domcomment_get_nodeTypeString( - IXMLDOMComment *iface, - BSTR* p) +static HRESULT WINAPI domcomment_get_nodeTypeString(IXMLDOMComment *iface, BSTR *p) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"comment", p); } -static HRESULT WINAPI domcomment_get_text( - IXMLDOMComment *iface, - BSTR* p) +static HRESULT WINAPI domcomment_get_text(IXMLDOMComment *iface, BSTR *p) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_text(&This->node, p); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_text(comment->node, p); } -static HRESULT WINAPI domcomment_put_text( - IXMLDOMComment *iface, - BSTR p) +static HRESULT WINAPI domcomment_put_text(IXMLDOMComment *iface, BSTR p) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - return node_put_text( &This->node, p ); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(p)); + + return node_put_data(comment->node, p); } -static HRESULT WINAPI domcomment_get_specified( - IXMLDOMComment *iface, - VARIANT_BOOL* isSpecified) +static HRESULT WINAPI domcomment_get_specified(IXMLDOMComment *iface, VARIANT_BOOL *v) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - FIXME("(%p)->(%p) stub!\n", This, isSpecified); - *isSpecified = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domcomment_get_definition( - IXMLDOMComment *iface, - IXMLDOMNode** definitionNode) +static HRESULT WINAPI domcomment_get_definition(IXMLDOMComment *iface, IXMLDOMNode **node) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - FIXME("(%p)->(%p)\n", This, definitionNode); - return E_NOTIMPL; + TRACE("%p, %p.\n", iface, node); + + return return_null_node(node); } -static HRESULT WINAPI domcomment_get_nodeTypedValue( - IXMLDOMComment *iface, - VARIANT* v) +static HRESULT WINAPI domcomment_get_nodeTypedValue(IXMLDOMComment *iface, VARIANT *v) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%p)\n", This, v); - return node_get_content(&This->node, v); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %p.\n", iface, v); + + return node_get_value(comment->node, v); } -static HRESULT WINAPI domcomment_put_nodeTypedValue( - IXMLDOMComment *iface, - VARIANT typedValue) +static HRESULT WINAPI domcomment_put_nodeTypedValue(IXMLDOMComment *iface, VARIANT v) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); + FIXME("%p, %s.\n", iface, debugstr_variant(&v)); + return E_NOTIMPL; } -static HRESULT WINAPI domcomment_get_dataType( - IXMLDOMComment *iface, - VARIANT* typename) +static HRESULT WINAPI domcomment_get_dataType(IXMLDOMComment *iface, VARIANT *v) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%p)\n", This, typename); - return return_null_var( typename ); + TRACE("%p, %p.\n", iface, v); + + return return_null_var(v); } -static HRESULT WINAPI domcomment_put_dataType( - IXMLDOMComment *iface, - BSTR p) +static HRESULT WINAPI domcomment_put_dataType(IXMLDOMComment *iface, BSTR p) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); + TRACE("%p, %s.\n", iface, debugstr_w(p)); - if(!p) + if (!p) return E_INVALIDARG; return E_FAIL; } -static HRESULT WINAPI domcomment_get_xml( - IXMLDOMComment *iface, - BSTR* p) +static HRESULT WINAPI domcomment_get_xml(IXMLDOMComment *iface, BSTR *p) { - domcomment *This = impl_from_IXMLDOMComment( iface ); + domcomment *comment = impl_from_IXMLDOMComment(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_xml(&This->node, FALSE, p); + return node_get_xml(comment->node, p); } -static HRESULT WINAPI domcomment_transformNode( - IXMLDOMComment *iface, - IXMLDOMNode *node, BSTR *p) +static HRESULT WINAPI domcomment_transformNode(IXMLDOMComment *iface, IXMLDOMNode *node, BSTR *p) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%p %p)\n", This, node, p); - return node_transform_node(&This->node, node, p); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %p, %p.\n", iface, node, p); + + return node_transform_node(comment->node, node, p); } -static HRESULT WINAPI domcomment_selectNodes( - IXMLDOMComment *iface, - BSTR p, IXMLDOMNodeList** outList) +static HRESULT WINAPI domcomment_selectNodes(IXMLDOMComment *iface, BSTR p, IXMLDOMNodeList **list) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); - return node_select_nodes(&This->node, p, outList); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), list); + + return node_select_nodes(comment->node, p, list); } -static HRESULT WINAPI domcomment_selectSingleNode( - IXMLDOMComment *iface, - BSTR p, IXMLDOMNode** outNode) +static HRESULT WINAPI domcomment_selectSingleNode(IXMLDOMComment *iface, BSTR p, IXMLDOMNode **node) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); - return node_select_singlenode(&This->node, p, outNode); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), node); + + return node_select_singlenode(comment->node, p, node); } -static HRESULT WINAPI domcomment_get_parsed( - IXMLDOMComment *iface, - VARIANT_BOOL* isParsed) +static HRESULT WINAPI domcomment_get_parsed(IXMLDOMComment *iface, VARIANT_BOOL *v) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - FIXME("(%p)->(%p) stub!\n", This, isParsed); - *isParsed = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domcomment_get_namespaceURI( - IXMLDOMComment *iface, - BSTR* p) +static HRESULT WINAPI domcomment_get_namespaceURI(IXMLDOMComment *iface, BSTR *p) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_namespaceURI(&This->node, p); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_namespaceURI(comment->node, p); } -static HRESULT WINAPI domcomment_get_prefix( - IXMLDOMComment *iface, - BSTR* prefix) +static HRESULT WINAPI domcomment_get_prefix(IXMLDOMComment *iface, BSTR *prefix) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%p)\n", This, prefix); - return return_null_bstr( prefix ); + TRACE("%p, %p.\n", iface, prefix); + + return return_null_bstr(prefix); } -static HRESULT WINAPI domcomment_get_baseName( - IXMLDOMComment *iface, - BSTR* name) +static HRESULT WINAPI domcomment_get_baseName(IXMLDOMComment *iface, BSTR *name) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%p)\n", This, name); - return return_null_bstr( name ); + TRACE("%p, %p.\n", iface, name); + + return return_null_bstr(name); } -static HRESULT WINAPI domcomment_transformNodeToObject( - IXMLDOMComment *iface, - IXMLDOMNode* domNode, VARIANT var1) +static HRESULT WINAPI domcomment_transformNodeToObject(IXMLDOMComment *iface, IXMLDOMNode *node, VARIANT v) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); + FIXME("%p, %p, %s.\n", iface, node, debugstr_variant(&v)); + return E_NOTIMPL; } -static HRESULT WINAPI domcomment_get_data( - IXMLDOMComment *iface, - BSTR *p) +static HRESULT WINAPI domcomment_get_data(IXMLDOMComment *iface, BSTR *p) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - HRESULT hr; - VARIANT vRet; - - TRACE("(%p)->(%p)\n", This, p); - - if(!p) - return E_INVALIDARG; + domcomment *comment = impl_from_IXMLDOMComment(iface); - hr = IXMLDOMComment_get_nodeValue( iface, &vRet ); - if(hr == S_OK) - { - *p = V_BSTR(&vRet); - } + TRACE("%p, %p.\n", iface, p); - return hr; + return node_get_data(comment->node, p); } -static HRESULT WINAPI domcomment_put_data( - IXMLDOMComment *iface, - BSTR data) +static HRESULT WINAPI domcomment_put_data(IXMLDOMComment *iface, BSTR data) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_w(data)); - return node_set_content(&This->node, data); + domcomment *comment = impl_from_IXMLDOMComment(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(data)); + + return node_put_data(comment->node, data); } -static HRESULT WINAPI domcomment_get_length( - IXMLDOMComment *iface, - LONG *len) +static HRESULT WINAPI domcomment_get_length(IXMLDOMComment *iface, LONG *len) { - domcomment *This = impl_from_IXMLDOMComment( iface ); HRESULT hr; BSTR data; - TRACE("(%p)->(%p)\n", This, len); + TRACE("%p, %p.\n", iface, len); if(!len) return E_INVALIDARG; @@ -609,37 +521,13 @@ static HRESULT WINAPI domcomment_substringData(IXMLDOMComment *iface, LONG offse return hr; } -static HRESULT WINAPI domcomment_appendData( - IXMLDOMComment *iface, - BSTR p) +static HRESULT WINAPI domcomment_appendData(IXMLDOMComment *iface, BSTR p) { - domcomment *This = impl_from_IXMLDOMComment( iface ); - HRESULT hr; - BSTR data; - LONG p_len; - - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - - /* Nothing to do if NULL or an Empty string passed in. */ - if((p_len = SysStringLen(p)) == 0) return S_OK; - - hr = IXMLDOMComment_get_data(iface, &data); - if(hr == S_OK) - { - LONG len = SysStringLen(data); - BSTR str = SysAllocStringLen(NULL, p_len + len); + domcomment *comment = impl_from_IXMLDOMComment(iface); - memcpy(str, data, len*sizeof(WCHAR)); - memcpy(&str[len], p, p_len*sizeof(WCHAR)); - str[len+p_len] = 0; + TRACE("%p, %s.\n", iface, debugstr_w(p)); - hr = IXMLDOMComment_put_data(iface, str); - - SysFreeString(str); - SysFreeString(data); - } - - return hr; + return node_append_data(comment->node, p); } static HRESULT WINAPI domcomment_insertData( @@ -807,30 +695,36 @@ static const struct IXMLDOMCommentVtbl domcomment_vtbl = domcomment_replaceData }; -static const tid_t domcomment_iface_tids[] = { +static const tid_t domcomment_iface_tids[] = +{ IXMLDOMComment_tid, 0 }; -static dispex_static_data_t domcomment_dispex = { +static dispex_static_data_t domcomment_dispex = +{ NULL, IXMLDOMComment_tid, NULL, domcomment_iface_tids }; -IUnknown* create_comment( xmlNodePtr comment ) +HRESULT create_comment(struct domnode *node, IUnknown **obj) { - domcomment *This; + domcomment *object; + + *obj = NULL; - This = malloc(sizeof(*This)); - if ( !This ) - return NULL; + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; - This->IXMLDOMComment_iface.lpVtbl = &domcomment_vtbl; - This->ref = 1; + object->IXMLDOMComment_iface.lpVtbl = &domcomment_vtbl; + object->refcount = 1; + object->node = domnode_addref(node); - init_xmlnode(&This->node, comment, (IXMLDOMNode*)&This->IXMLDOMComment_iface, &domcomment_dispex); + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMComment_iface, &domcomment_dispex); - return (IUnknown*)&This->IXMLDOMComment_iface; + *obj = (IUnknown *)&object->IXMLDOMComment_iface; + + return S_OK; } diff --git a/dlls/msxml3/docfrag.c b/dlls/msxml3/docfrag.c index ab16fbe2c4d..6f3e55704b2 100644 --- a/dlls/msxml3/docfrag.c +++ b/dlls/msxml3/docfrag.c @@ -21,8 +21,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> #include "windef.h" #include "winbase.h" @@ -36,51 +34,55 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); -typedef struct _domfrag +typedef struct _docfrag { - xmlnode node; + DispatchEx dispex; IXMLDOMDocumentFragment IXMLDOMDocumentFragment_iface; - LONG ref; -} domfrag; + LONG refcount; + struct domnode *node; +} docfrag; -static const tid_t domfrag_se_tids[] = { +static const tid_t docfrag_se_tids[] = +{ IXMLDOMNode_tid, IXMLDOMDocumentFragment_tid, NULL_tid }; -static inline domfrag *impl_from_IXMLDOMDocumentFragment( IXMLDOMDocumentFragment *iface ) +static inline docfrag *impl_from_IXMLDOMDocumentFragment( IXMLDOMDocumentFragment *iface ) { - return CONTAINING_RECORD(iface, domfrag, IXMLDOMDocumentFragment_iface); + return CONTAINING_RECORD(iface, docfrag, IXMLDOMDocumentFragment_iface); } -static HRESULT WINAPI domfrag_QueryInterface( - IXMLDOMDocumentFragment *iface, - REFIID riid, - void** ppvObject ) +static HRESULT WINAPI docfrag_QueryInterface(IXMLDOMDocumentFragment *iface, REFIID riid, void **obj) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); - if ( IsEqualGUID( riid, &IID_IXMLDOMDocumentFragment ) || - IsEqualGUID( riid, &IID_IXMLDOMNode ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IUnknown ) ) + if (IsEqualGUID( riid, &IID_IXMLDOMDocumentFragment) || + IsEqualGUID( riid, &IID_IXMLDOMNode) || + IsEqualGUID( riid, &IID_IDispatch) || + IsEqualGUID( riid, &IID_IUnknown)) + { + *obj = iface; + } + else if (dispex_query_interface(&docfrag->dispex, riid, obj)) { - *ppvObject = iface; + return *obj ? S_OK : E_NOINTERFACE; } - else if(node_query_interface(&This->node, riid, ppvObject)) + else if (node_query_interface(docfrag->node, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } - else if(IsEqualGUID( riid, &IID_ISupportErrorInfo )) + else if (IsEqualGUID(riid, &IID_ISupportErrorInfo)) { - return node_create_supporterrorinfo(domfrag_se_tids, ppvObject); + return node_create_supporterrorinfo(docfrag_se_tids, obj); } else { TRACE("Unsupported interface %s\n", debugstr_guid(riid)); - *ppvObject = NULL; + *obj = NULL; return E_NOINTERFACE; } @@ -88,503 +90,435 @@ static HRESULT WINAPI domfrag_QueryInterface( return S_OK; } -static ULONG WINAPI domfrag_AddRef(IXMLDOMDocumentFragment *iface) +static ULONG WINAPI docfrag_AddRef(IXMLDOMDocumentFragment *iface) { - domfrag *domfrag = impl_from_IXMLDOMDocumentFragment(iface); - ULONG ref = InterlockedIncrement(&domfrag->ref); - TRACE("%p, refcount %lu.\n", iface, ref); - return ref; + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + ULONG refcount = InterlockedIncrement(&docfrag->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); + + return refcount; } -static ULONG WINAPI domfrag_Release(IXMLDOMDocumentFragment *iface) +static ULONG WINAPI docfrag_Release(IXMLDOMDocumentFragment *iface) { - domfrag *domfrag = impl_from_IXMLDOMDocumentFragment(iface); - ULONG ref = InterlockedDecrement(&domfrag->ref); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + ULONG refcount = InterlockedDecrement(&docfrag->refcount); - TRACE("%p, refcount %lu.\n", iface, ref); + TRACE("%p, refcount %lu.\n", iface, refcount); - if (!ref) + if (!refcount) { - destroy_xmlnode(&domfrag->node); - free(domfrag); + domnode_release(docfrag->node); + free(docfrag); } - return ref; + return refcount; } -static HRESULT WINAPI domfrag_GetTypeInfoCount( - IXMLDOMDocumentFragment *iface, - UINT* pctinfo ) +static HRESULT WINAPI docfrag_GetTypeInfoCount(IXMLDOMDocumentFragment *iface, UINT *count) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + return IDispatchEx_GetTypeInfoCount(&docfrag->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI domfrag_GetTypeInfo( - IXMLDOMDocumentFragment *iface, - UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI docfrag_GetTypeInfo(IXMLDOMDocumentFragment *iface, UINT index, LCID lcid, ITypeInfo **ti) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + return IDispatchEx_GetTypeInfo(&docfrag->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI domfrag_GetIDsOfNames( - IXMLDOMDocumentFragment *iface, - REFIID riid, LPOLESTR* rgszNames, - UINT cNames, LCID lcid, DISPID* rgDispId ) +static HRESULT WINAPI docfrag_GetIDsOfNames(IXMLDOMDocumentFragment *iface, REFIID riid, + LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + return IDispatchEx_GetIDsOfNames(&docfrag->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); } -static HRESULT WINAPI domfrag_Invoke( - IXMLDOMDocumentFragment *iface, - DISPID dispIdMember, REFIID riid, LCID lcid, - WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr ) +static HRESULT WINAPI docfrag_Invoke(IXMLDOMDocumentFragment *iface, DISPID dispIdMember, REFIID riid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *puArgErr) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + return IDispatchEx_Invoke(&docfrag->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, flags, + params, result, ei, puArgErr); } -static HRESULT WINAPI domfrag_get_nodeName( - IXMLDOMDocumentFragment *iface, - BSTR* p ) +static HRESULT WINAPI docfrag_get_nodeName(IXMLDOMDocumentFragment *iface, BSTR *p) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"#document-fragment", p); } -static HRESULT WINAPI domfrag_get_nodeValue( - IXMLDOMDocumentFragment *iface, - VARIANT* value) +static HRESULT WINAPI docfrag_get_nodeValue(IXMLDOMDocumentFragment *iface, VARIANT *value) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%p)\n", This, value); + TRACE("%p, %p.\n", iface, value); + return return_null_var(value); } -static HRESULT WINAPI domfrag_put_nodeValue( - IXMLDOMDocumentFragment *iface, - VARIANT value) +static HRESULT WINAPI docfrag_put_nodeValue(IXMLDOMDocumentFragment *iface, VARIANT value) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + TRACE("%p, %s.\n", iface, debugstr_variant(&value)); + return E_FAIL; } -static HRESULT WINAPI domfrag_get_nodeType( - IXMLDOMDocumentFragment *iface, - DOMNodeType* domNodeType ) +static HRESULT WINAPI docfrag_get_nodeType(IXMLDOMDocumentFragment *iface, DOMNodeType *type) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - - TRACE("(%p)->(%p)\n", This, domNodeType); + TRACE("%p, %p.\n", iface, type); - *domNodeType = NODE_DOCUMENT_FRAGMENT; + *type = NODE_DOCUMENT_FRAGMENT; return S_OK; } -static HRESULT WINAPI domfrag_get_parentNode( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode** parent ) +static HRESULT WINAPI docfrag_get_parentNode(IXMLDOMDocumentFragment *iface, IXMLDOMNode **parent) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); - TRACE("(%p)->(%p)\n", This, parent); + TRACE("%p, %p.\n", iface, parent); - return node_get_parent(&This->node, parent); + return node_get_parent(docfrag->node, parent); } -static HRESULT WINAPI domfrag_get_childNodes( - IXMLDOMDocumentFragment *iface, - IXMLDOMNodeList** outList) +static HRESULT WINAPI docfrag_get_childNodes(IXMLDOMDocumentFragment *iface, IXMLDOMNodeList **list) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); - TRACE("(%p)->(%p)\n", This, outList); + TRACE("%p, %p.\n", iface, list); - return node_get_child_nodes(&This->node, outList); + return node_get_child_nodes(docfrag->node, list); } -static HRESULT WINAPI domfrag_get_firstChild( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI docfrag_get_firstChild(IXMLDOMDocumentFragment *iface, IXMLDOMNode **node) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_first_child(&This->node, domNode); + return node_get_first_child(docfrag->node, node); } -static HRESULT WINAPI domfrag_get_lastChild( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI docfrag_get_lastChild(IXMLDOMDocumentFragment *iface, IXMLDOMNode **node) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_last_child(&This->node, domNode); + return node_get_last_child(docfrag->node, node); } -static HRESULT WINAPI domfrag_get_previousSibling( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI docfrag_get_previousSibling(IXMLDOMDocumentFragment *iface, IXMLDOMNode **node) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + TRACE("%p, %p.\n", iface, node); - TRACE("(%p)->(%p)\n", This, domNode); - - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI domfrag_get_nextSibling( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI docfrag_get_nextSibling(IXMLDOMDocumentFragment *iface, IXMLDOMNode **node) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI domfrag_get_attributes( - IXMLDOMDocumentFragment *iface, - IXMLDOMNamedNodeMap** attributeMap) +static HRESULT WINAPI docfrag_get_attributes(IXMLDOMDocumentFragment *iface, IXMLDOMNamedNodeMap **map) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - - TRACE("(%p)->(%p)\n", This, attributeMap); + TRACE("%p, %p.\n", iface, map); - return return_null_ptr((void**)attributeMap); + return return_null_ptr((void **)map); } -static HRESULT WINAPI domfrag_insertBefore( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode* newNode, VARIANT refChild, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI docfrag_insertBefore(IXMLDOMDocumentFragment *iface, IXMLDOMNode* newNode, + VARIANT refChild, IXMLDOMNode **outOldNode) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); - TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), outOldNode); + TRACE("%p, %p, %s, %p.\n", iface, newNode, debugstr_variant(&refChild), outOldNode); /* TODO: test */ - return node_insert_before(&This->node, newNode, &refChild, outOldNode); + return node_insert_before(docfrag->node, newNode, &refChild, outOldNode); } -static HRESULT WINAPI domfrag_replaceChild( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode* newNode, - IXMLDOMNode* oldNode, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI docfrag_replaceChild(IXMLDOMDocumentFragment *iface, IXMLDOMNode *newNode, + IXMLDOMNode *oldNode, IXMLDOMNode **outOldNode) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); - TRACE("(%p)->(%p %p %p)\n", This, newNode, oldNode, outOldNode); + TRACE("%p, %p, %p, %p.\n", iface, newNode, oldNode, outOldNode); /* TODO: test */ - return node_replace_child(&This->node, newNode, oldNode, outOldNode); + return node_replace_child(docfrag->node, newNode, oldNode, outOldNode); } -static HRESULT WINAPI domfrag_removeChild( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode *child, IXMLDOMNode **oldChild) +static HRESULT WINAPI docfrag_removeChild(IXMLDOMDocumentFragment *iface, IXMLDOMNode *child, IXMLDOMNode **oldChild) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%p %p)\n", This, child, oldChild); - return node_remove_child(&This->node, child, oldChild); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %p, %p.\n", iface, child, oldChild); + + return node_remove_child(docfrag->node, child, oldChild); } -static HRESULT WINAPI domfrag_appendChild( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode *child, IXMLDOMNode **outChild) +static HRESULT WINAPI docfrag_appendChild(IXMLDOMDocumentFragment *iface, IXMLDOMNode *child, IXMLDOMNode **outChild) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%p %p)\n", This, child, outChild); - return node_append_child(&This->node, child, outChild); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %p, %p.\n", iface, child, outChild); + + return node_append_child(docfrag->node, child, outChild); } -static HRESULT WINAPI domfrag_hasChildNodes( - IXMLDOMDocumentFragment *iface, - VARIANT_BOOL *ret) +static HRESULT WINAPI docfrag_hasChildNodes(IXMLDOMDocumentFragment *iface, VARIANT_BOOL *ret) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%p)\n", This, ret); - return node_has_childnodes(&This->node, ret); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %p.\n", iface, ret); + + return node_has_childnodes(docfrag->node, ret); } -static HRESULT WINAPI domfrag_get_ownerDocument( - IXMLDOMDocumentFragment *iface, - IXMLDOMDocument **doc) +static HRESULT WINAPI docfrag_get_ownerDocument(IXMLDOMDocumentFragment *iface, IXMLDOMDocument **doc) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%p)\n", This, doc); - return node_get_owner_doc(&This->node, doc); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %p.\n", iface, doc); + + return node_get_owner_document(docfrag->node, doc); } -static HRESULT WINAPI domfrag_cloneNode( - IXMLDOMDocumentFragment *iface, - VARIANT_BOOL deep, IXMLDOMNode** outNode) +static HRESULT WINAPI docfrag_cloneNode(IXMLDOMDocumentFragment *iface, VARIANT_BOOL deep, IXMLDOMNode **node) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%d %p)\n", This, deep, outNode); - return node_clone( &This->node, deep, outNode ); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %d, %p.\n", iface, deep, node); + + return node_clone(docfrag->node, deep, node); } -static HRESULT WINAPI domfrag_get_nodeTypeString( - IXMLDOMDocumentFragment *iface, - BSTR* p) +static HRESULT WINAPI docfrag_get_nodeTypeString(IXMLDOMDocumentFragment *iface, BSTR *p) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"documentfragment", p); } -static HRESULT WINAPI domfrag_get_text( - IXMLDOMDocumentFragment *iface, - BSTR* p) +static HRESULT WINAPI docfrag_get_text(IXMLDOMDocumentFragment *iface, BSTR *p) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_text(&This->node, p); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_text(docfrag->node, p); } -static HRESULT WINAPI domfrag_put_text( - IXMLDOMDocumentFragment *iface, - BSTR p) +static HRESULT WINAPI docfrag_put_text(IXMLDOMDocumentFragment *iface, BSTR p) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - return node_put_text( &This->node, p ); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(p)); + + return node_put_data(docfrag->node, p); } -static HRESULT WINAPI domfrag_get_specified( - IXMLDOMDocumentFragment *iface, - VARIANT_BOOL* isSpecified) +static HRESULT WINAPI docfrag_get_specified(IXMLDOMDocumentFragment *iface, VARIANT_BOOL *v) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - FIXME("(%p)->(%p) stub!\n", This, isSpecified); - *isSpecified = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domfrag_get_definition( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode** definitionNode) +static HRESULT WINAPI docfrag_get_definition(IXMLDOMDocumentFragment *iface, IXMLDOMNode **node) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - FIXME("(%p)->(%p)\n", This, definitionNode); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domfrag_get_nodeTypedValue( - IXMLDOMDocumentFragment *iface, - VARIANT *v) +static HRESULT WINAPI docfrag_get_nodeTypedValue(IXMLDOMDocumentFragment *iface, VARIANT *v) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%p)\n", This, v); + TRACE("%p, %p.\n", iface, v); + return return_null_var(v); } -static HRESULT WINAPI domfrag_put_nodeTypedValue( - IXMLDOMDocumentFragment *iface, - VARIANT typedValue) +static HRESULT WINAPI docfrag_put_nodeTypedValue(IXMLDOMDocumentFragment *iface, VARIANT v) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); + FIXME("%p, %s.\n", iface, debugstr_variant(&v)); + return E_NOTIMPL; } -static HRESULT WINAPI domfrag_get_dataType( - IXMLDOMDocumentFragment *iface, - VARIANT* typename) +static HRESULT WINAPI docfrag_get_dataType(IXMLDOMDocumentFragment *iface, VARIANT *v) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%p)\n", This, typename); - return return_null_var( typename ); + TRACE("%p, %p.\n", iface, v); + + return return_null_var(v); } -static HRESULT WINAPI domfrag_put_dataType( - IXMLDOMDocumentFragment *iface, - BSTR p) +static HRESULT WINAPI docfrag_put_dataType(IXMLDOMDocumentFragment *iface, BSTR p) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); + TRACE("%p, %s.\n", iface, debugstr_w(p)); - if(!p) + if (!p) return E_INVALIDARG; return E_FAIL; } -static HRESULT WINAPI domfrag_get_xml( - IXMLDOMDocumentFragment *iface, - BSTR* p) +static HRESULT WINAPI docfrag_get_xml(IXMLDOMDocumentFragment *iface, BSTR *p) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_xml(&This->node, FALSE, p); + return node_get_xml(docfrag->node, p); } -static HRESULT WINAPI domfrag_transformNode( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode *node, BSTR *p) +static HRESULT WINAPI docfrag_transformNode(IXMLDOMDocumentFragment *iface, IXMLDOMNode *node, BSTR *p) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%p %p)\n", This, node, p); - return node_transform_node(&This->node, node, p); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %p, %p.\n", iface, node, p); + + return node_transform_node(docfrag->node, node, p); } -static HRESULT WINAPI domfrag_selectNodes( - IXMLDOMDocumentFragment *iface, - BSTR p, IXMLDOMNodeList** outList) +static HRESULT WINAPI docfrag_selectNodes(IXMLDOMDocumentFragment *iface, BSTR p, IXMLDOMNodeList **list) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); - return node_select_nodes(&This->node, p, outList); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), list); + + return node_select_nodes(docfrag->node, p, list); } -static HRESULT WINAPI domfrag_selectSingleNode( - IXMLDOMDocumentFragment *iface, - BSTR p, IXMLDOMNode** outNode) +static HRESULT WINAPI docfrag_selectSingleNode(IXMLDOMDocumentFragment *iface, BSTR p, IXMLDOMNode **node) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); - return node_select_singlenode(&This->node, p, outNode); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), node); + + return node_select_singlenode(docfrag->node, p, node); } -static HRESULT WINAPI domfrag_get_parsed( - IXMLDOMDocumentFragment *iface, - VARIANT_BOOL* isParsed) +static HRESULT WINAPI docfrag_get_parsed(IXMLDOMDocumentFragment *iface, VARIANT_BOOL *v) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - FIXME("(%p)->(%p) stub!\n", This, isParsed); - *isParsed = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domfrag_get_namespaceURI( - IXMLDOMDocumentFragment *iface, - BSTR* p) +static HRESULT WINAPI docfrag_get_namespaceURI(IXMLDOMDocumentFragment *iface, BSTR *p) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_namespaceURI(&This->node, p); + docfrag *docfrag = impl_from_IXMLDOMDocumentFragment(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_namespaceURI(docfrag->node, p); } -static HRESULT WINAPI domfrag_get_prefix( - IXMLDOMDocumentFragment *iface, - BSTR* prefix) +static HRESULT WINAPI docfrag_get_prefix(IXMLDOMDocumentFragment *iface, BSTR *prefix) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - TRACE("(%p)->(%p)\n", This, prefix); - return return_null_bstr( prefix ); + TRACE("%p, %p.\n", iface, prefix); + + return return_null_bstr(prefix); } -static HRESULT WINAPI domfrag_get_baseName( - IXMLDOMDocumentFragment *iface, - BSTR* name) +static HRESULT WINAPI docfrag_get_baseName(IXMLDOMDocumentFragment *iface, BSTR *name) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - FIXME("(%p)->(%p): needs test\n", This, name); - return return_null_bstr( name ); + FIXME("%p, %p: needs test\n", iface, name); + + return return_null_bstr(name); } -static HRESULT WINAPI domfrag_transformNodeToObject( - IXMLDOMDocumentFragment *iface, - IXMLDOMNode* domNode, VARIANT var1) +static HRESULT WINAPI docfrag_transformNodeToObject(IXMLDOMDocumentFragment *iface, IXMLDOMNode *node, VARIANT var) { - domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); - FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); + FIXME("%p, %p, %s.\n", iface, node, debugstr_variant(&var)); + return E_NOTIMPL; } -static const struct IXMLDOMDocumentFragmentVtbl domfrag_vtbl = -{ - domfrag_QueryInterface, - domfrag_AddRef, - domfrag_Release, - domfrag_GetTypeInfoCount, - domfrag_GetTypeInfo, - domfrag_GetIDsOfNames, - domfrag_Invoke, - domfrag_get_nodeName, - domfrag_get_nodeValue, - domfrag_put_nodeValue, - domfrag_get_nodeType, - domfrag_get_parentNode, - domfrag_get_childNodes, - domfrag_get_firstChild, - domfrag_get_lastChild, - domfrag_get_previousSibling, - domfrag_get_nextSibling, - domfrag_get_attributes, - domfrag_insertBefore, - domfrag_replaceChild, - domfrag_removeChild, - domfrag_appendChild, - domfrag_hasChildNodes, - domfrag_get_ownerDocument, - domfrag_cloneNode, - domfrag_get_nodeTypeString, - domfrag_get_text, - domfrag_put_text, - domfrag_get_specified, - domfrag_get_definition, - domfrag_get_nodeTypedValue, - domfrag_put_nodeTypedValue, - domfrag_get_dataType, - domfrag_put_dataType, - domfrag_get_xml, - domfrag_transformNode, - domfrag_selectNodes, - domfrag_selectSingleNode, - domfrag_get_parsed, - domfrag_get_namespaceURI, - domfrag_get_prefix, - domfrag_get_baseName, - domfrag_transformNodeToObject +static const struct IXMLDOMDocumentFragmentVtbl docfrag_vtbl = +{ + docfrag_QueryInterface, + docfrag_AddRef, + docfrag_Release, + docfrag_GetTypeInfoCount, + docfrag_GetTypeInfo, + docfrag_GetIDsOfNames, + docfrag_Invoke, + docfrag_get_nodeName, + docfrag_get_nodeValue, + docfrag_put_nodeValue, + docfrag_get_nodeType, + docfrag_get_parentNode, + docfrag_get_childNodes, + docfrag_get_firstChild, + docfrag_get_lastChild, + docfrag_get_previousSibling, + docfrag_get_nextSibling, + docfrag_get_attributes, + docfrag_insertBefore, + docfrag_replaceChild, + docfrag_removeChild, + docfrag_appendChild, + docfrag_hasChildNodes, + docfrag_get_ownerDocument, + docfrag_cloneNode, + docfrag_get_nodeTypeString, + docfrag_get_text, + docfrag_put_text, + docfrag_get_specified, + docfrag_get_definition, + docfrag_get_nodeTypedValue, + docfrag_put_nodeTypedValue, + docfrag_get_dataType, + docfrag_put_dataType, + docfrag_get_xml, + docfrag_transformNode, + docfrag_selectNodes, + docfrag_selectSingleNode, + docfrag_get_parsed, + docfrag_get_namespaceURI, + docfrag_get_prefix, + docfrag_get_baseName, + docfrag_transformNodeToObject }; -static const tid_t domfrag_iface_tids[] = { +static const tid_t docfrag_iface_tids[] = +{ IXMLDOMDocumentFragment_tid, 0 }; -static dispex_static_data_t domfrag_dispex = { +static dispex_static_data_t docfrag_dispex = +{ NULL, IXMLDOMDocumentFragment_tid, NULL, - domfrag_iface_tids + docfrag_iface_tids }; -IUnknown* create_doc_fragment( xmlNodePtr fragment ) +HRESULT create_doc_fragment(struct domnode *node, IUnknown **obj) { - domfrag *This; + docfrag *object; - This = malloc(sizeof(*This)); - if ( !This ) - return NULL; + *obj = NULL; - This->IXMLDOMDocumentFragment_iface.lpVtbl = &domfrag_vtbl; - This->ref = 1; + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; - init_xmlnode(&This->node, fragment, (IXMLDOMNode*)&This->IXMLDOMDocumentFragment_iface, &domfrag_dispex); + object->IXMLDOMDocumentFragment_iface.lpVtbl = &docfrag_vtbl; + object->refcount = 1; + object->node = domnode_addref(node); - return (IUnknown*)&This->IXMLDOMDocumentFragment_iface; + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMDocumentFragment_iface, &docfrag_dispex); + + *obj = (IUnknown *)&object->IXMLDOMDocumentFragment_iface; + + return S_OK; } diff --git a/dlls/msxml3/doctype.c b/dlls/msxml3/doctype.c index 5edc928e0c0..59a2f54c39a 100644 --- a/dlls/msxml3/doctype.c +++ b/dlls/msxml3/doctype.c @@ -21,8 +21,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> #include "windef.h" #include "winbase.h" @@ -39,468 +37,395 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); typedef struct _domdoctype { - xmlnode node; + DispatchEx dispex; IXMLDOMDocumentType IXMLDOMDocumentType_iface; - LONG ref; + LONG refcount; + struct domnode *node; } domdoctype; +static const tid_t doctype_se_tids[] = +{ + IXMLDOMNode_tid, + IXMLDOMDocumentType_tid, + NULL_tid +}; + static inline domdoctype *impl_from_IXMLDOMDocumentType( IXMLDOMDocumentType *iface ) { return CONTAINING_RECORD(iface, domdoctype, IXMLDOMDocumentType_iface); } -static HRESULT WINAPI domdoctype_QueryInterface( - IXMLDOMDocumentType *iface, - REFIID riid, - void** ppvObject ) +static HRESULT WINAPI domdoctype_QueryInterface(IXMLDOMDocumentType *iface, REFIID riid, void **obj) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); + domdoctype *doctype = impl_from_IXMLDOMDocumentType(iface); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); - if ( IsEqualGUID( riid, &IID_IXMLDOMDocumentType ) || - IsEqualGUID( riid, &IID_IXMLDOMNode ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IUnknown ) ) + if (IsEqualGUID(riid, &IID_IXMLDOMDocumentType) || + IsEqualGUID(riid, &IID_IXMLDOMNode) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IUnknown)) + { + *obj = &doctype->IXMLDOMDocumentType_iface; + } + else if (dispex_query_interface(&doctype->dispex, riid, obj)) + { + return *obj ? S_OK : E_NOINTERFACE; + } + else if (node_query_interface(doctype->node, riid, obj)) { - *ppvObject = &This->IXMLDOMDocumentType_iface; + return *obj ? S_OK : E_NOINTERFACE; } - else if(node_query_interface(&This->node, riid, ppvObject)) + else if (IsEqualGUID(riid, &IID_ISupportErrorInfo)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return node_create_supporterrorinfo(doctype_se_tids, obj); } else { TRACE("interface %s not implemented\n", debugstr_guid(riid)); - *ppvObject = NULL; + *obj = NULL; return E_NOINTERFACE; } - IUnknown_AddRef( (IUnknown*)*ppvObject ); + IUnknown_AddRef( (IUnknown*)*obj ); return S_OK; } static ULONG WINAPI domdoctype_AddRef(IXMLDOMDocumentType *iface) { domdoctype *doctype = impl_from_IXMLDOMDocumentType(iface); - LONG ref = InterlockedIncrement(&doctype->ref); - TRACE("%p, refcount %ld.\n", iface, ref); - return ref; + LONG refcount = InterlockedIncrement(&doctype->refcount); + + TRACE("%p, refcount %ld.\n", iface, refcount); + + return refcount; } static ULONG WINAPI domdoctype_Release(IXMLDOMDocumentType *iface) { domdoctype *doctype = impl_from_IXMLDOMDocumentType(iface); - ULONG ref = InterlockedDecrement(&doctype->ref); + ULONG refcount = InterlockedDecrement(&doctype->refcount); - TRACE("%p, refcount %ld.\n", iface, ref); + TRACE("%p, refcount %ld.\n", iface, refcount); - if (!ref) + if (!refcount) { - destroy_xmlnode(&doctype->node); + domnode_release(doctype->node); free(doctype); } - return ref; + return refcount; } -static HRESULT WINAPI domdoctype_GetTypeInfoCount( - IXMLDOMDocumentType *iface, - UINT* pctinfo ) +static HRESULT WINAPI domdoctype_GetTypeInfoCount(IXMLDOMDocumentType *iface, UINT *count) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); + domdoctype *doctype = impl_from_IXMLDOMDocumentType(iface); + return IDispatchEx_GetTypeInfoCount(&doctype->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI domdoctype_GetTypeInfo( - IXMLDOMDocumentType *iface, - UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI domdoctype_GetTypeInfo(IXMLDOMDocumentType *iface, UINT index, LCID lcid, ITypeInfo **ti) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + domdoctype *doctype = impl_from_IXMLDOMDocumentType(iface); + return IDispatchEx_GetTypeInfo(&doctype->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI domdoctype_GetIDsOfNames( - IXMLDOMDocumentType *iface, - REFIID riid, LPOLESTR* rgszNames, - UINT cNames, LCID lcid, DISPID* rgDispId ) +static HRESULT WINAPI domdoctype_GetIDsOfNames(IXMLDOMDocumentType *iface, REFIID riid, LPOLESTR* rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, + domdoctype *doctype = impl_from_IXMLDOMDocumentType(iface); + return IDispatchEx_GetIDsOfNames(&doctype->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); } -static HRESULT WINAPI domdoctype_Invoke( - IXMLDOMDocumentType *iface, - DISPID dispIdMember, REFIID riid, LCID lcid, - WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr ) +static HRESULT WINAPI domdoctype_Invoke(IXMLDOMDocumentType *iface, DISPID dispIdMember, REFIID riid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *puArgErr) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + domdoctype *doctype = impl_from_IXMLDOMDocumentType(iface); + return IDispatchEx_Invoke(&doctype->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, flags, params, + result, ei, puArgErr); } -static HRESULT WINAPI domdoctype_get_nodeName( - IXMLDOMDocumentType *iface, - BSTR* p ) +static HRESULT WINAPI domdoctype_get_nodeName(IXMLDOMDocumentType *iface, BSTR *p) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_nodeName(&This->node, p); + domdoctype *doctype = impl_from_IXMLDOMDocumentType(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_name(doctype->node, p); } -static HRESULT WINAPI domdoctype_get_nodeValue( - IXMLDOMDocumentType *iface, - VARIANT* value) +static HRESULT WINAPI domdoctype_get_nodeValue(IXMLDOMDocumentType *iface, VARIANT *v) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, value); - return E_NOTIMPL; + TRACE("%p, %p.\n", iface, v); + + return return_null_var(v); } -static HRESULT WINAPI domdoctype_put_nodeValue( - IXMLDOMDocumentType *iface, - VARIANT value) +static HRESULT WINAPI domdoctype_put_nodeValue(IXMLDOMDocumentType *iface, VARIANT v) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&value)); + FIXME("%p, %s: stub\n", iface, debugstr_variant(&v)); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_nodeType( - IXMLDOMDocumentType *iface, - DOMNodeType* domNodeType ) +static HRESULT WINAPI domdoctype_get_nodeType(IXMLDOMDocumentType *iface, DOMNodeType *type) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - - TRACE("(%p)->(%p)\n", This, domNodeType); + TRACE("%p, %p.\n", iface, type); - *domNodeType = NODE_DOCUMENT_TYPE; + *type = NODE_DOCUMENT_TYPE; return S_OK; } -static HRESULT WINAPI domdoctype_get_parentNode( - IXMLDOMDocumentType *iface, - IXMLDOMNode** parent ) +static HRESULT WINAPI domdoctype_get_parentNode(IXMLDOMDocumentType *iface, IXMLDOMNode **parent) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, parent); + FIXME("%p, %p: stub\n", iface, parent); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_childNodes( - IXMLDOMDocumentType *iface, - IXMLDOMNodeList** outList) +static HRESULT WINAPI domdoctype_get_childNodes(IXMLDOMDocumentType *iface, IXMLDOMNodeList **list) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, outList); + FIXME("%p, %p: stub\n", iface, list); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_firstChild( - IXMLDOMDocumentType *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domdoctype_get_firstChild(IXMLDOMDocumentType *iface, IXMLDOMNode **node) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, domNode); + FIXME("%p, %p: stub\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_lastChild( - IXMLDOMDocumentType *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domdoctype_get_lastChild(IXMLDOMDocumentType *iface, IXMLDOMNode **node) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, domNode); + FIXME("%p, %p: stub\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_previousSibling( - IXMLDOMDocumentType *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domdoctype_get_previousSibling(IXMLDOMDocumentType *iface, IXMLDOMNode **node) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, domNode); + FIXME("%p, %p: stub\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_nextSibling( - IXMLDOMDocumentType *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domdoctype_get_nextSibling(IXMLDOMDocumentType *iface, IXMLDOMNode **node) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, domNode); + FIXME("%p, %p: stub\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_attributes( - IXMLDOMDocumentType *iface, - IXMLDOMNamedNodeMap** attributeMap) +static HRESULT WINAPI domdoctype_get_attributes(IXMLDOMDocumentType *iface, IXMLDOMNamedNodeMap **map) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, attributeMap); + FIXME("%p, %p: stub\n", iface, map); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_insertBefore( - IXMLDOMDocumentType *iface, - IXMLDOMNode* newNode, VARIANT refChild, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI domdoctype_insertBefore(IXMLDOMDocumentType *iface, IXMLDOMNode *node, + VARIANT refChild, IXMLDOMNode **out_node) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - - FIXME("(%p)->(%p %s %p): stub\n", This, newNode, debugstr_variant(&refChild), outOldNode); + FIXME("%p, %p, %s, %p: stub\n", iface, node, debugstr_variant(&refChild), out_node); return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_replaceChild( - IXMLDOMDocumentType *iface, - IXMLDOMNode* newNode, - IXMLDOMNode* oldNode, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI domdoctype_replaceChild(IXMLDOMDocumentType *iface, IXMLDOMNode *newNode, + IXMLDOMNode *oldNode, IXMLDOMNode **outOldNode) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - - FIXME("(%p)->(%p %p %p): stub\n", This, newNode, oldNode, outOldNode); + FIXME("%p, %p, %p, %p: stub\n", iface, newNode, oldNode, outOldNode); return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_removeChild( - IXMLDOMDocumentType *iface, - IXMLDOMNode* domNode, IXMLDOMNode** oldNode) +static HRESULT WINAPI domdoctype_removeChild(IXMLDOMDocumentType *iface, IXMLDOMNode *node, + IXMLDOMNode **oldNode) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p %p): stub\n", This, domNode, oldNode); + FIXME("%p, %p, %p: stub\n", iface, node, oldNode); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_appendChild( - IXMLDOMDocumentType *iface, - IXMLDOMNode* newNode, IXMLDOMNode** outNewNode) +static HRESULT WINAPI domdoctype_appendChild(IXMLDOMDocumentType *iface, IXMLDOMNode *newNode, + IXMLDOMNode **outNewNode) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p %p): stub\n", This, newNode, outNewNode); + FIXME("%p, %p, %p: stub\n", iface, newNode, outNewNode); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_hasChildNodes( - IXMLDOMDocumentType *iface, - VARIANT_BOOL* pbool) +static HRESULT WINAPI domdoctype_hasChildNodes(IXMLDOMDocumentType *iface, VARIANT_BOOL *v) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, pbool); + FIXME("%p, %p: stub\n", iface, v); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_ownerDocument( - IXMLDOMDocumentType *iface, - IXMLDOMDocument** domDocument) +static HRESULT WINAPI domdoctype_get_ownerDocument(IXMLDOMDocumentType *iface, IXMLDOMDocument **doc) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, domDocument); + FIXME("%p, %p: stub\n", iface, doc); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_cloneNode( - IXMLDOMDocumentType *iface, - VARIANT_BOOL deep, IXMLDOMNode** outNode) +static HRESULT WINAPI domdoctype_cloneNode(IXMLDOMDocumentType *iface, VARIANT_BOOL deep, IXMLDOMNode **node) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%d %p): stub\n", This, deep, outNode); + FIXME("%p, %d, %p: stub\n", iface, deep, node); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_nodeTypeString( - IXMLDOMDocumentType *iface, - BSTR* p) +static HRESULT WINAPI domdoctype_get_nodeTypeString(IXMLDOMDocumentType *iface, BSTR *p) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, p); + FIXME("%p, %p: stub\n", iface, p); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_text( - IXMLDOMDocumentType *iface, - BSTR* p) +static HRESULT WINAPI domdoctype_get_text(IXMLDOMDocumentType *iface, BSTR *p) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, p); - return E_NOTIMPL; + TRACE("%p, %p.\n", iface, p); + + return return_bstr(L"", p); } -static HRESULT WINAPI domdoctype_put_text( - IXMLDOMDocumentType *iface, - BSTR p) +static HRESULT WINAPI domdoctype_put_text(IXMLDOMDocumentType *iface, BSTR p) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%s): stub\n", This, debugstr_w(p)); + FIXME("%p, %s: stub\n", iface, debugstr_w(p)); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_specified( - IXMLDOMDocumentType *iface, - VARIANT_BOOL* isSpecified) +static HRESULT WINAPI domdoctype_get_specified(IXMLDOMDocumentType *iface, VARIANT_BOOL *v) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, isSpecified); + FIXME("%p, %p: stub\n", iface, v); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_definition( - IXMLDOMDocumentType *iface, - IXMLDOMNode** definitionNode) +static HRESULT WINAPI domdoctype_get_definition(IXMLDOMDocumentType *iface, IXMLDOMNode **node) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p)\n", This, definitionNode); + FIXME("%p, %p\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_nodeTypedValue( - IXMLDOMDocumentType *iface, - VARIANT* v) +static HRESULT WINAPI domdoctype_get_nodeTypedValue(IXMLDOMDocumentType *iface, VARIANT *v) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - TRACE("(%p)->(%p)\n", This, v); + TRACE("%p, %p.\n", iface, v); + return return_null_var(v); } -static HRESULT WINAPI domdoctype_put_nodeTypedValue( - IXMLDOMDocumentType *iface, - VARIANT value) +static HRESULT WINAPI domdoctype_put_nodeTypedValue(IXMLDOMDocumentType *iface, VARIANT value) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&value)); + FIXME("%p, %s: stub\n", iface, debugstr_variant(&value)); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_dataType( - IXMLDOMDocumentType *iface, - VARIANT* typename) +static HRESULT WINAPI domdoctype_get_dataType(IXMLDOMDocumentType *iface, VARIANT *v) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, typename); + FIXME("%p, %p: stub\n", iface, v); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_put_dataType( - IXMLDOMDocumentType *iface, - BSTR p) +static HRESULT WINAPI domdoctype_put_dataType(IXMLDOMDocumentType *iface, BSTR p) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%s): stub\n", This, debugstr_w(p)); + FIXME("%p, %s: stub\n", iface, debugstr_w(p)); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_xml( - IXMLDOMDocumentType *iface, - BSTR* p) +static HRESULT WINAPI domdoctype_get_xml(IXMLDOMDocumentType *iface, BSTR *p) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, p); - return E_NOTIMPL; + domdoctype *doctype = impl_from_IXMLDOMDocumentType(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_xml(doctype->node, p); } -static HRESULT WINAPI domdoctype_transformNode( - IXMLDOMDocumentType *iface, - IXMLDOMNode* domNode, BSTR* p) +static HRESULT WINAPI domdoctype_transformNode(IXMLDOMDocumentType *iface, IXMLDOMNode *node, BSTR *p) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p %p): stub\n", This, domNode, p); + FIXME("%p, %p, %p: stub\n", iface, node, p); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_selectNodes( - IXMLDOMDocumentType *iface, - BSTR p, IXMLDOMNodeList** outList) +static HRESULT WINAPI domdoctype_selectNodes(IXMLDOMDocumentType *iface, BSTR p, IXMLDOMNodeList **list) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(p), outList); + FIXME("%p, %s, %p: stub\n", iface, debugstr_w(p), list); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_selectSingleNode( - IXMLDOMDocumentType *iface, - BSTR p, IXMLDOMNode** outNode) +static HRESULT WINAPI domdoctype_selectSingleNode(IXMLDOMDocumentType *iface, BSTR p, IXMLDOMNode **node) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(p), outNode); + FIXME("%p, %s, %p: stub\n", iface, debugstr_w(p), node); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_parsed( - IXMLDOMDocumentType *iface, - VARIANT_BOOL* isParsed) +static HRESULT WINAPI domdoctype_get_parsed(IXMLDOMDocumentType *iface, VARIANT_BOOL *v) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, isParsed); + FIXME("%p, %p: stub\n", iface, v); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_namespaceURI( - IXMLDOMDocumentType *iface, - BSTR* p) +static HRESULT WINAPI domdoctype_get_namespaceURI(IXMLDOMDocumentType *iface, BSTR *p) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, p); + FIXME("%p, %p: stub\n", iface, p); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_prefix( - IXMLDOMDocumentType *iface, - BSTR* prefix) +static HRESULT WINAPI domdoctype_get_prefix(IXMLDOMDocumentType *iface, BSTR *prefix) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, prefix); + FIXME("%p, %p: stub\n", iface, prefix); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_baseName( - IXMLDOMDocumentType *iface, - BSTR* name) +static HRESULT WINAPI domdoctype_get_baseName(IXMLDOMDocumentType *iface, BSTR *name) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, name); + FIXME("%p, %p: stub\n", iface, name); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_transformNodeToObject( - IXMLDOMDocumentType *iface, - IXMLDOMNode* domNode, VARIANT var1) +static HRESULT WINAPI domdoctype_transformNodeToObject(IXMLDOMDocumentType *iface, IXMLDOMNode *node, VARIANT var1) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p %s): stub\n", This, domNode, debugstr_variant(&var1)); + FIXME("%p, %p, %s: stub\n", iface, node, debugstr_variant(&var1)); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_name( - IXMLDOMDocumentType *iface, - BSTR *p) +static HRESULT WINAPI domdoctype_get_name(IXMLDOMDocumentType *iface, BSTR *p) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_nodeName(&This->node, p); + domdoctype *doctype = impl_from_IXMLDOMDocumentType(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_name(doctype->node, p); } -static HRESULT WINAPI domdoctype_get_entities( - IXMLDOMDocumentType *iface, - IXMLDOMNamedNodeMap **entityMap) +static HRESULT WINAPI domdoctype_get_entities(IXMLDOMDocumentType *iface, IXMLDOMNamedNodeMap **entities) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, entityMap); + FIXME("%p, %p: stub\n", iface, entities); + return E_NOTIMPL; } -static HRESULT WINAPI domdoctype_get_notations( - IXMLDOMDocumentType *iface, - IXMLDOMNamedNodeMap **notationMap) +static HRESULT WINAPI domdoctype_get_notations(IXMLDOMDocumentType *iface, IXMLDOMNamedNodeMap **notations) { - domdoctype *This = impl_from_IXMLDOMDocumentType( iface ); - FIXME("(%p)->(%p): stub\n", This, notationMap); + FIXME("%p, %p: stub\n", iface, notations); + return E_NOTIMPL; } @@ -554,31 +479,36 @@ static const struct IXMLDOMDocumentTypeVtbl domdoctype_vtbl = domdoctype_get_notations }; -static const tid_t domdoctype_iface_tids[] = { +static const tid_t domdoctype_iface_tids[] = +{ IXMLDOMDocumentType_tid, 0 }; -static dispex_static_data_t domdoctype_dispex = { +static dispex_static_data_t domdoctype_dispex = +{ NULL, IXMLDOMDocumentType_tid, NULL, domdoctype_iface_tids }; -IUnknown* create_doc_type( xmlNodePtr doctype ) +HRESULT create_doc_type(struct domnode *node, IUnknown **obj) { - domdoctype *This; + domdoctype *object; + + *obj = NULL; - This = malloc(sizeof(*This)); - if ( !This ) - return NULL; + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; - This->IXMLDOMDocumentType_iface.lpVtbl = &domdoctype_vtbl; - This->ref = 1; + object->IXMLDOMDocumentType_iface.lpVtbl = &domdoctype_vtbl; + object->refcount = 1; + object->node = domnode_addref(node); - init_xmlnode(&This->node, doctype, (IXMLDOMNode*)&This->IXMLDOMDocumentType_iface, - &domdoctype_dispex); + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMDocumentType_iface, &domdoctype_dispex); - return (IUnknown*)&This->IXMLDOMDocumentType_iface; + *obj = (IUnknown *)&object->IXMLDOMDocumentType_iface; + + return S_OK; } diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c index 505ac496eed..c19bcde03ab 100644 --- a/dlls/msxml3/domdoc.c +++ b/dlls/msxml3/domdoc.c @@ -24,11 +24,7 @@ #include <stdarg.h> #include <assert.h> #include <libxml/parser.h> -#include <libxml/xmlerror.h> #include <libxml/xpathInternals.h> -# include <libxml/xmlsave.h> -#include <libxml/SAX2.h> -#include <libxml/parserInternals.h> #include "windef.h" #include "winbase.h" @@ -49,23 +45,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); -/* Anything that passes the test_get_ownerDocument() - * tests can go here (data shared between all instances). - * We need to preserve this when reloading a document, - * and also need access to it from the libxml backend. */ -typedef struct { - LONG refs; - MSXML_VERSION version; - VARIANT_BOOL preserving; - VARIANT_BOOL validating; - IXMLDOMSchemaCollection2* schemaCache; - struct list selectNsList; - xmlChar const* selectNsStr; - LONG selectNsStr_len; - BOOL XPath; - IUri *uri; -} domdoc_properties; - typedef struct ConnectionPoint ConnectionPoint; typedef struct domdoc domdoc; @@ -96,18 +75,19 @@ typedef enum { struct domdoc { - xmlnode node; + DispatchEx dispex; IXMLDOMDocument3 IXMLDOMDocument3_iface; IPersistStreamInit IPersistStreamInit_iface; IObjectWithSite IObjectWithSite_iface; IObjectSafety IObjectSafety_iface; IConnectionPointContainer IConnectionPointContainer_iface; - LONG ref; + LONG refcount; VARIANT_BOOL async; VARIANT_BOOL resolving; - domdoc_properties* properties; HRESULT error; + struct domnode *node; + /* IObjectWithSite */ IUnknown *site; IUri *base_uri; @@ -158,76 +138,13 @@ static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *ifac return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface); } -/* - In native windows, the whole lifetime management of XMLDOMNodes is - managed automatically using reference counts. Wine emulates that by - maintaining a reference count to the document that is increased for - each IXMLDOMNode pointer passed out for this document. If all these - pointers are gone, the document is unreachable and gets freed, that - is, all nodes in the tree of the document get freed. - - You are able to create nodes that are associated to a document (in - fact, in msxml's XMLDOM model, all nodes are associated to a document), - but not in the tree of that document, for example using the createFoo - functions from IXMLDOMDocument. These nodes do not get cleaned up - by libxml, so we have to do it ourselves. - - To catch these nodes, a list of "orphan nodes" is introduced. - It contains pointers to all roots of node trees that are - associated with the document without being part of the document - tree. All nodes with parent==NULL (except for the document root nodes) - should be in the orphan node list of their document. All orphan nodes - get freed together with the document itself. - */ - -typedef struct _xmldoc_priv { - LONG refs; - struct list orphans; - domdoc_properties* properties; -} xmldoc_priv; - -typedef struct _orphan_entry { - struct list entry; - xmlNode * node; -} orphan_entry; - -typedef struct _select_ns_entry { - struct list entry; - xmlChar const* prefix; - xmlChar prefix_end; - xmlChar const* href; - xmlChar href_end; -} select_ns_entry; - -static inline xmldoc_priv * priv_from_xmlDocPtr(const xmlDocPtr doc) +int registerNamespaces(struct domnode *node, xmlXPathContextPtr ctxt) { - return doc->_private; -} - -static inline domdoc_properties * properties_from_xmlDocPtr(xmlDocPtr doc) -{ - return priv_from_xmlDocPtr(doc)->properties; -} - -BOOL is_xpathmode(const xmlDocPtr doc) -{ - return properties_from_xmlDocPtr(doc)->XPath; -} - -void set_xpathmode(xmlDocPtr doc, BOOL xpath) -{ - properties_from_xmlDocPtr(doc)->XPath = xpath; -} - -int registerNamespaces(xmlXPathContextPtr ctxt) -{ - int n = 0; + struct domnode *doc = node->owner ? node->owner : node; const select_ns_entry* ns = NULL; - const struct list* pNsList = &properties_from_xmlDocPtr(ctxt->doc)->selectNsList; - - TRACE("(%p)\n", ctxt); + int n = 0; - LIST_FOR_EACH_ENTRY( ns, pNsList, select_ns_entry, entry ) + LIST_FOR_EACH_ENTRY( ns, &doc->properties->selectNsList, select_ns_entry, entry ) { xmlXPathRegisterNs(ctxt, ns->prefix, ns->href); ++n; @@ -236,7 +153,7 @@ int registerNamespaces(xmlXPathContextPtr ctxt) return n; } -static inline void clear_selectNsList(struct list* pNsList) +void domdoc_properties_clear_selection_namespaces(struct list *pNsList) { select_ns_entry *ns, *ns2; LIST_FOR_EACH_ENTRY_SAFE( ns, ns2, pNsList, select_ns_entry, entry ) @@ -246,469 +163,28 @@ static inline void clear_selectNsList(struct list* pNsList) list_init(pNsList); } -static xmldoc_priv * create_priv(void) -{ - xmldoc_priv *priv; - priv = malloc(sizeof(*priv)); - - if (priv) - { - priv->refs = 0; - list_init( &priv->orphans ); - priv->properties = NULL; - } - - return priv; -} - -static domdoc_properties *create_properties(MSXML_VERSION version) -{ - domdoc_properties *properties = malloc(sizeof(domdoc_properties)); - - properties->refs = 1; - list_init(&properties->selectNsList); - properties->preserving = VARIANT_FALSE; - properties->validating = VARIANT_TRUE; - properties->schemaCache = NULL; - properties->selectNsStr = calloc(1, sizeof(xmlChar)); - properties->selectNsStr_len = 0; - - /* properties that are dependent on object versions */ - properties->version = version; - properties->XPath = (version == MSXML4 || version == MSXML6); - - /* document uri */ - properties->uri = NULL; - - return properties; -} - -static domdoc_properties* copy_properties(domdoc_properties const* properties) -{ - domdoc_properties* pcopy = malloc(sizeof(domdoc_properties)); - select_ns_entry const* ns = NULL; - select_ns_entry* new_ns = NULL; - int len = (properties->selectNsStr_len+1)*sizeof(xmlChar); - ptrdiff_t offset; - - if (pcopy) - { - pcopy->refs = 1; - pcopy->version = properties->version; - pcopy->preserving = properties->preserving; - pcopy->validating = properties->validating; - pcopy->schemaCache = properties->schemaCache; - if (pcopy->schemaCache) - IXMLDOMSchemaCollection2_AddRef(pcopy->schemaCache); - pcopy->XPath = properties->XPath; - pcopy->selectNsStr_len = properties->selectNsStr_len; - list_init( &pcopy->selectNsList ); - pcopy->selectNsStr = malloc(len); - memcpy((xmlChar*)pcopy->selectNsStr, properties->selectNsStr, len); - offset = pcopy->selectNsStr - properties->selectNsStr; - - LIST_FOR_EACH_ENTRY( ns, (&properties->selectNsList), select_ns_entry, entry ) - { - new_ns = malloc(sizeof(select_ns_entry)); - memcpy(new_ns, ns, sizeof(select_ns_entry)); - new_ns->href += offset; - new_ns->prefix += offset; - list_add_tail(&pcopy->selectNsList, &new_ns->entry); - } - - pcopy->uri = properties->uri; - if (pcopy->uri) - IUri_AddRef(pcopy->uri); - } - - return pcopy; -} - -static domdoc_properties * properties_add_ref(domdoc_properties *properties) -{ - LONG ref; - - if (!properties) return NULL; - - ref = InterlockedIncrement(&properties->refs); - TRACE("%p, %ld.\n", properties, ref); - return properties; -} - -static void properties_release(domdoc_properties *properties) -{ - LONG ref; - - if (!properties) return; - - ref = InterlockedDecrement(&properties->refs); - - TRACE("%p, %ld.\n", properties, ref); - - if (ref < 0) - WARN("negative refcount, expect troubles\n"); - - if (ref == 0) - { - if (properties->schemaCache) - IXMLDOMSchemaCollection2_Release(properties->schemaCache); - clear_selectNsList(&properties->selectNsList); - free((xmlChar*)properties->selectNsStr); - if (properties->uri) - IUri_Release(properties->uri); - free(properties); - } -} - -static void release_namespaces(domdoc *This) -{ - if (This->namespaces) - { - IXMLDOMSchemaCollection2_Release(This->namespaces); - This->namespaces = NULL; - } -} - -/* links a "<?xml" node as a first child */ -void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node) -{ - assert(doc != NULL); - if (doc->standalone != -1) xmlAddPrevSibling( doc->children, node ); -} - -/* unlinks a first "<?xml" child if it was created */ -xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc) -{ - static const xmlChar xmlA[] = "xml"; - xmlNodePtr node, first_child; - - assert(doc != NULL); - - /* xml declaration node could be created automatically after parsing or added - to a tree later */ - first_child = doc->children; - if (first_child && first_child->type == XML_PI_NODE && xmlStrEqual(first_child->name, xmlA)) - { - node = first_child; - xmlUnlinkNode( node ); - } - else - node = NULL; - - return node; -} - -MSXML_VERSION xmldoc_version(xmlDocPtr doc) -{ - return properties_from_xmlDocPtr(doc)->version; -} - -BOOL is_preserving_whitespace(xmlNodePtr node) -{ - domdoc_properties* properties = NULL; - /* during parsing the xmlDoc._private stuff is not there */ - if (priv_from_xmlDocPtr(node->doc)) - properties = properties_from_xmlDocPtr(node->doc); - return ((properties && properties->preserving == VARIANT_TRUE) || - xmlNodeGetSpacePreserve(node) == 1); -} - -static inline BOOL strn_isspace(xmlChar const* str, int len) -{ - for (; str && len > 0 && *str; ++str, --len) - if (!isspace(*str)) - break; - - return len == 0; -} - -static void sax_characters(void *ctx, const xmlChar *ch, int len) -{ - xmlParserCtxtPtr ctxt; - const domdoc *This; - - ctxt = (xmlParserCtxtPtr) ctx; - This = (const domdoc*) ctxt->_private; - - if (ctxt->node) - { - xmlChar cur = *(ctxt->input->cur); - - /* Characters are reported with multiple calls, for example each charref is reported with a separate - call and then parser appends it to a single text node or creates a new node if not created. - It's not possible to tell if it's ignorable data or not just looking at data itself cause it could be - space chars that separate charrefs or similar case. We only need to skip leading and trailing spaces, - or whole node if it has nothing but space chars, so to detect leading space node->last is checked that - contains text node pointer if already created, trailing spaces are detected directly looking at parser input - for next '<' opening bracket - similar logic is used by libxml2 itself. Basically 'cur' == '<' means the last - chunk of char data, in case it's not the last chunk we check for previously added node type and if it's not - a text node it's safe to ignore. - - Note that during domdoc_loadXML() the xmlDocPtr->_private data is not available. */ - - if (!This->properties->preserving && - !is_preserving_whitespace(ctxt->node) && - strn_isspace(ch, len) && - (!ctxt->node->last || - ((ctxt->node->last && (cur == '<' || ctxt->node->last->type != XML_TEXT_NODE)) - ))) - { - /* Keep information about ignorable whitespace text node in previous or parent node */ - if (ctxt->node->last) - *(DWORD*)&ctxt->node->last->_private |= NODE_PRIV_TRAILING_IGNORABLE_WS; - else if (ctxt->node->type != XML_DOCUMENT_NODE) - *(DWORD*)&ctxt->node->_private |= NODE_PRIV_CHILD_IGNORABLE_WS; - return; - } - } - - xmlSAX2Characters(ctxt, ch, len); -} - -static void LIBXML2_LOG_CALLBACK sax_error(void* ctx, char const* msg, ...) -{ - va_list ap; - va_start(ap, msg); - LIBXML2_CALLBACK_ERR(doparse, msg, ap); - va_end(ap); -} - -static void LIBXML2_LOG_CALLBACK sax_warning(void* ctx, char const* msg, ...) -{ - va_list ap; - va_start(ap, msg); - LIBXML2_CALLBACK_WARN(doparse, msg, ap); - va_end(ap); -} - -static void sax_serror(void* ctx, const xmlError* err) -{ - LIBXML2_CALLBACK_SERROR(doparse, err); -} - -static xmlDocPtr doparse(domdoc* This, char const* ptr, int len, xmlCharEncoding encoding) -{ - char *ctx_encoding; - xmlDocPtr doc = NULL; - xmlParserCtxtPtr pctx; - static xmlSAXHandler sax_handler = { - xmlSAX2InternalSubset, /* internalSubset */ - xmlSAX2IsStandalone, /* isStandalone */ - xmlSAX2HasInternalSubset, /* hasInternalSubset */ - xmlSAX2HasExternalSubset, /* hasExternalSubset */ - xmlSAX2ResolveEntity, /* resolveEntity */ - xmlSAX2GetEntity, /* getEntity */ - xmlSAX2EntityDecl, /* entityDecl */ - xmlSAX2NotationDecl, /* notationDecl */ - xmlSAX2AttributeDecl, /* attributeDecl */ - xmlSAX2ElementDecl, /* elementDecl */ - xmlSAX2UnparsedEntityDecl, /* unparsedEntityDecl */ - xmlSAX2SetDocumentLocator, /* setDocumentLocator */ - xmlSAX2StartDocument, /* startDocument */ - xmlSAX2EndDocument, /* endDocument */ - xmlSAX2StartElement, /* startElement */ - xmlSAX2EndElement, /* endElement */ - xmlSAX2Reference, /* reference */ - sax_characters, /* characters */ - sax_characters, /* ignorableWhitespace */ - xmlSAX2ProcessingInstruction, /* processingInstruction */ - xmlSAX2Comment, /* comment */ - sax_warning, /* warning */ - sax_error, /* error */ - sax_error, /* fatalError */ - xmlSAX2GetParameterEntity, /* getParameterEntity */ - xmlSAX2CDataBlock, /* cdataBlock */ - xmlSAX2ExternalSubset, /* externalSubset */ - 0, /* initialized */ - NULL, /* _private */ - xmlSAX2StartElementNs, /* startElementNs */ - xmlSAX2EndElementNs, /* endElementNs */ - sax_serror /* serror */ - }; - - pctx = xmlCreateMemoryParserCtxt(ptr, len); - if (!pctx) - { - ERR("Failed to create parser context\n"); - return NULL; - } - - if (pctx->sax) xmlFree(pctx->sax); - pctx->sax = &sax_handler; - pctx->_private = This; - pctx->recovery = 0; - - if (encoding != XML_CHAR_ENCODING_NONE) - xmlSwitchEncoding(pctx, encoding); - - xmlParseDocument(pctx); - - if (pctx->wellFormed) - { - doc = pctx->myDoc; - } - else - { - xmlFreeDoc(pctx->myDoc); - pctx->myDoc = NULL; - } - pctx->sax = NULL; - ctx_encoding = (char *)pctx->encoding; - pctx->encoding = NULL; - xmlFreeParserCtxt(pctx); - - /* TODO: put this in one of the SAX callbacks */ - /* create first child as a <?xml...?> */ - if (doc && doc->standalone != -1) - { - xmlNodePtr node; - char buff[30]; - xmlChar *xmlbuff = (xmlChar*)buff; - - node = xmlNewDocPI( doc, (xmlChar*)"xml", NULL ); - - /* version attribute can't be omitted */ - sprintf(buff, "version=\"%s\"", doc->version ? (char*)doc->version : "1.0"); - xmlNodeAddContent( node, xmlbuff ); - - if (ctx_encoding) - { - sprintf(buff, " encoding=\"%s\"", ctx_encoding); - xmlNodeAddContent( node, xmlbuff ); - } - - if (doc->standalone != -2) - { - sprintf(buff, " standalone=\"%s\"", doc->standalone == 0 ? "no" : "yes"); - xmlNodeAddContent( node, xmlbuff ); - } - - xmldoc_link_xmldecl( doc, node ); - } - - xmlFree( ctx_encoding ); - return doc; -} - -void xmldoc_init(xmlDocPtr doc, MSXML_VERSION version) +static void release_namespaces(domdoc *doc) { - doc->_private = create_priv(); - priv_from_xmlDocPtr(doc)->properties = create_properties(version); -} - -LONG xmldoc_add_refs(xmlDocPtr doc, LONG refs) -{ - LONG ref = InterlockedExchangeAdd(&priv_from_xmlDocPtr(doc)->refs, refs) + refs; - TRACE("%p, refcount %ld.\n", doc, ref); - return ref; -} - -LONG xmldoc_add_ref(xmlDocPtr doc) -{ - return xmldoc_add_refs(doc, 1); -} - -LONG xmldoc_release_refs(xmlDocPtr doc, LONG refs) -{ - xmldoc_priv *priv = priv_from_xmlDocPtr(doc); - LONG ref = InterlockedExchangeAdd(&priv->refs, -refs) - refs; - - TRACE("%p, refcount %ld.\n", doc, ref); - - if (ref < 0) - WARN("negative refcount, expect troubles\n"); - - if (ref == 0) + if (doc->namespaces) { - orphan_entry *orphan, *orphan2; - TRACE("freeing docptr %p\n", doc); - - LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry ) - { - xmlFreeNode( orphan->node ); - free( orphan ); - } - properties_release(priv->properties); - free(doc->_private); - - xmlFreeDoc(doc); + IXMLDOMSchemaCollection2_Release(doc->namespaces); + doc->namespaces = NULL; } - - return ref; } -LONG xmldoc_release(xmlDocPtr doc) +MSXML_VERSION domdoc_version(const struct domnode *doc) { - return xmldoc_release_refs(doc, 1); + assert(doc->type == NODE_DOCUMENT); + return doc->properties->version; } -HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node) +static void attach_doc_node(domdoc *doc, struct domnode *node) { - xmldoc_priv *priv = priv_from_xmlDocPtr(doc); - orphan_entry *entry; - - entry = malloc(sizeof(*entry)); - if(!entry) - return E_OUTOFMEMORY; + release_namespaces(doc); - entry->node = node; - list_add_head( &priv->orphans, &entry->entry ); - return S_OK; -} - -HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node) -{ - xmldoc_priv *priv = priv_from_xmlDocPtr(doc); - orphan_entry *entry, *entry2; - - LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry ) - { - if( entry->node == node ) - { - list_remove( &entry->entry ); - free( entry ); - return S_OK; - } - } - - return S_FALSE; -} - -static inline xmlDocPtr get_doc( domdoc *This ) -{ - return This->node.node->doc; -} - -static HRESULT attach_xmldoc(domdoc *This, xmlDocPtr xml ) -{ - release_namespaces(This); - - if(This->node.node) - { - properties_release(properties_from_xmlDocPtr(get_doc(This))); - priv_from_xmlDocPtr(get_doc(This))->properties = NULL; - if (xmldoc_release(get_doc(This)) != 0) - { - /* The xmlDocPtr object can no longer use the properties of this - * domdoc object. So give it its own copy. - */ - priv_from_xmlDocPtr(get_doc(This))->properties = - copy_properties(This->properties); - } - } - - This->node.node = (xmlNodePtr) xml; - - if(This->node.node) - { - xmldoc_add_ref(get_doc(This)); - /* Only attach new xmlDocPtr objects, i.e. ones for which properties - * is still NULL. - */ - priv_from_xmlDocPtr(get_doc(This))->properties = properties_add_ref(This->properties); - } - - return S_OK; + domnode_addref(node); + node_move_children(doc->node, node); + domnode_release(node); } static inline domdoc *impl_from_IXMLDOMDocument3( IXMLDOMDocument3 *iface ) @@ -736,61 +212,53 @@ static inline domdoc *impl_from_IConnectionPointContainer(IConnectionPointContai return CONTAINING_RECORD(iface, domdoc, IConnectionPointContainer_iface); } -/************************************************************************ - * domdoc implementation of IPersistStream. - */ -static HRESULT WINAPI PersistStreamInit_QueryInterface( - IPersistStreamInit *iface, REFIID riid, void **ppvObj) +static HRESULT WINAPI PersistStreamInit_QueryInterface(IPersistStreamInit *iface, REFIID riid, void **obj) { - domdoc* This = impl_from_IPersistStreamInit(iface); - return IXMLDOMDocument3_QueryInterface(&This->IXMLDOMDocument3_iface, riid, ppvObj); + domdoc *doc = impl_from_IPersistStreamInit(iface); + return IXMLDOMDocument3_QueryInterface(&doc->IXMLDOMDocument3_iface, riid, obj); } -static ULONG WINAPI PersistStreamInit_AddRef( - IPersistStreamInit *iface) +static ULONG WINAPI PersistStreamInit_AddRef(IPersistStreamInit *iface) { - domdoc* This = impl_from_IPersistStreamInit(iface); - return IXMLDOMDocument3_AddRef(&This->IXMLDOMDocument3_iface); + domdoc *doc = impl_from_IPersistStreamInit(iface); + return IXMLDOMDocument3_AddRef(&doc->IXMLDOMDocument3_iface); } -static ULONG WINAPI PersistStreamInit_Release( - IPersistStreamInit *iface) +static ULONG WINAPI PersistStreamInit_Release(IPersistStreamInit *iface) { - domdoc* This = impl_from_IPersistStreamInit(iface); - return IXMLDOMDocument3_Release(&This->IXMLDOMDocument3_iface); + domdoc *doc = impl_from_IPersistStreamInit(iface); + return IXMLDOMDocument3_Release(&doc->IXMLDOMDocument3_iface); } -static HRESULT WINAPI PersistStreamInit_GetClassID( - IPersistStreamInit *iface, CLSID *classid) +static HRESULT WINAPI PersistStreamInit_GetClassID(IPersistStreamInit *iface, CLSID *clsid) { - domdoc* This = impl_from_IPersistStreamInit(iface); - TRACE("(%p)->(%p)\n", This, classid); + domdoc *doc = impl_from_IPersistStreamInit(iface); - if(!classid) + TRACE("%p, %p.\n", iface, clsid); + + if (!clsid) return E_POINTER; - *classid = *DOMDocument_version(This->properties->version); + *clsid = *DOMDocument_version(doc->node->properties->version); return S_OK; } -static HRESULT WINAPI PersistStreamInit_IsDirty( - IPersistStreamInit *iface) +static HRESULT WINAPI PersistStreamInit_IsDirty(IPersistStreamInit *iface) { - domdoc *This = impl_from_IPersistStreamInit(iface); - FIXME("(%p): stub!\n", This); + FIXME("%p: stub!\n", iface); + return S_FALSE; } static HRESULT domdoc_load_from_stream(domdoc *doc, ISequentialStream *stream) { - DWORD read, written, len; - xmlDocPtr xmldoc = NULL; + LARGE_INTEGER zero = {{0}}; + struct domnode *node; + DWORD read, written; IStream *hstream; - HGLOBAL hglobal; BYTE buf[4096]; HRESULT hr; - char *ptr; hstream = NULL; hr = CreateStreamOnHGlobal(NULL, TRUE, &hstream); @@ -801,7 +269,7 @@ static HRESULT domdoc_load_from_stream(domdoc *doc, ISequentialStream *stream) { ISequentialStream_Read(stream, buf, sizeof(buf), &read); hr = IStream_Write(hstream, buf, read, &written); - } while(SUCCEEDED(hr) && written != 0 && read != 0); + } while (SUCCEEDED(hr) && written != 0 && read != 0); if (FAILED(hr)) { @@ -810,41 +278,30 @@ static HRESULT domdoc_load_from_stream(domdoc *doc, ISequentialStream *stream) return hr; } - hr = GetHGlobalFromStream(hstream, &hglobal); - if (FAILED(hr)) - { - IStream_Release(hstream); - return hr; - } - - len = GlobalSize(hglobal); - ptr = GlobalLock(hglobal); - if (len) - xmldoc = doparse(doc, ptr, len, XML_CHAR_ENCODING_NONE); - GlobalUnlock(hglobal); + hr = IStream_Seek(hstream, zero, STREAM_SEEK_SET, NULL); + hr = parse_stream((ISequentialStream *)hstream, false, doc->node->properties->preserving, &node); IStream_Release(hstream); - if (!xmldoc) + if (!node) { ERR("Failed to parse xml\n"); return E_FAIL; } - xmldoc->_private = create_priv(); - - return attach_xmldoc(doc, xmldoc); + attach_doc_node(doc, node); + return S_OK; } static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, IStream *stream) { - domdoc *This = impl_from_IPersistStreamInit(iface); + domdoc *doc = impl_from_IPersistStreamInit(iface); - TRACE("(%p)->(%p)\n", This, stream); + TRACE("%p, %p.\n", iface, stream); if (!stream) return E_INVALIDARG; - return This->error = domdoc_load_from_stream(This, (ISequentialStream*)stream); + return doc->error = domdoc_load_from_stream(doc, (ISequentialStream *)stream); } static HRESULT WINAPI PersistStreamInit_Save( @@ -870,19 +327,17 @@ static HRESULT WINAPI PersistStreamInit_Save( return hr; } -static HRESULT WINAPI PersistStreamInit_GetSizeMax( - IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize) +static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface, ULARGE_INTEGER *size) { - domdoc *This = impl_from_IPersistStreamInit(iface); - TRACE("(%p)->(%p)\n", This, pcbSize); + TRACE("%p, %p.\n", iface, size); + return E_NOTIMPL; } -static HRESULT WINAPI PersistStreamInit_InitNew( - IPersistStreamInit *iface) +static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface) { - domdoc *This = impl_from_IPersistStreamInit(iface); - TRACE("(%p)\n", This); + TRACE("%p.\n", iface); + return S_OK; } @@ -899,9 +354,8 @@ static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable = PersistStreamInit_InitNew }; -/* IXMLDOMDocument3 interface */ - -static const tid_t domdoc_se_tids[] = { +static const tid_t domdoc_se_tids[] = +{ IXMLDOMNode_tid, IXMLDOMDocument_tid, IXMLDOMDocument2_tid, @@ -909,47 +363,51 @@ static const tid_t domdoc_se_tids[] = { NULL_tid }; -static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument3 *iface, REFIID riid, void** ppvObject ) +static HRESULT WINAPI domdoc_QueryInterface(IXMLDOMDocument3 *iface, REFIID riid, void **obj) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject ); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); - *ppvObject = NULL; + *obj = NULL; - if ( IsEqualGUID( riid, &IID_IUnknown ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IXMLDOMNode ) || - IsEqualGUID( riid, &IID_IXMLDOMDocument ) || - IsEqualGUID( riid, &IID_IXMLDOMDocument2 )|| - IsEqualGUID( riid, &IID_IXMLDOMDocument3 )) + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IXMLDOMNode) || + IsEqualGUID(riid, &IID_IXMLDOMDocument) || + IsEqualGUID(riid, &IID_IXMLDOMDocument2)|| + IsEqualGUID(riid, &IID_IXMLDOMDocument3)) { - *ppvObject = iface; + *obj = iface; } else if (IsEqualGUID(&IID_IPersistStream, riid) || IsEqualGUID(&IID_IPersistStreamInit, riid)) { - *ppvObject = &This->IPersistStreamInit_iface; + *obj = &doc->IPersistStreamInit_iface; } else if (IsEqualGUID(&IID_IObjectWithSite, riid)) { - *ppvObject = &This->IObjectWithSite_iface; + *obj = &doc->IObjectWithSite_iface; } else if (IsEqualGUID(&IID_IObjectSafety, riid)) { - *ppvObject = &This->IObjectSafety_iface; + *obj = &doc->IObjectSafety_iface; } else if( IsEqualGUID( riid, &IID_ISupportErrorInfo )) { - return node_create_supporterrorinfo(domdoc_se_tids, ppvObject); + return node_create_supporterrorinfo(domdoc_se_tids, obj); + } + else if (dispex_query_interface(&doc->dispex, riid, obj)) + { + return *obj ? S_OK : E_NOINTERFACE; } - else if(node_query_interface(&This->node, riid, ppvObject)) + else if (node_query_interface(doc->node, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } - else if (IsEqualGUID( riid, &IID_IConnectionPointContainer )) + else if (IsEqualGUID(riid, &IID_IConnectionPointContainer)) { - *ppvObject = &This->IConnectionPointContainer_iface; + *obj = &doc->IConnectionPointContainer_iface; } else { @@ -957,7 +415,7 @@ static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument3 *iface, REFIID rii return E_NOINTERFACE; } - IUnknown_AddRef((IUnknown*)*ppvObject); + IUnknown_AddRef((IUnknown *)*obj); return S_OK; } @@ -965,577 +423,370 @@ static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument3 *iface, REFIID rii static ULONG WINAPI domdoc_AddRef( IXMLDOMDocument3 *iface ) { domdoc *doc = impl_from_IXMLDOMDocument3(iface); - ULONG ref = InterlockedIncrement(&doc->ref); - TRACE("%p, refcount %ld.\n", iface, ref); - return ref; + ULONG refcount = InterlockedIncrement(&doc->refcount); + + TRACE("%p, refcount %ld.\n", iface, refcount); + + return refcount; } static ULONG WINAPI domdoc_Release( IXMLDOMDocument3 *iface ) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - LONG ref = InterlockedDecrement( &This->ref ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + LONG refcount = InterlockedDecrement(&doc->refcount); - TRACE("%p, refcount %ld.\n", iface, ref); + TRACE("%p, refcount %ld.\n", iface, refcount); - if (!ref) + if (!refcount) { int eid; - if (This->site) - IUnknown_Release( This->site ); - if (This->base_uri) - IUri_Release( This->base_uri ); - destroy_xmlnode(&This->node); + if (doc->site) + IUnknown_Release(doc->site); + if (doc->base_uri) + IUri_Release(doc->base_uri); + + domnode_release(doc->node); for (eid = 0; eid < EVENTID_LAST; eid++) - if (This->events[eid]) IDispatch_Release(This->events[eid]); + if (doc->events[eid]) IDispatch_Release(doc->events[eid]); - properties_release(This->properties); - release_namespaces(This); - free(This); + release_namespaces(doc); + free(doc); } - return ref; + return refcount; } -static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument3 *iface, UINT* pctinfo ) +static HRESULT WINAPI domdoc_GetTypeInfoCount(IXMLDOMDocument3 *iface, UINT *count) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + return IDispatchEx_GetTypeInfoCount(&doc->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI domdoc_GetTypeInfo( - IXMLDOMDocument3 *iface, - UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) +static HRESULT WINAPI domdoc_GetTypeInfo(IXMLDOMDocument3 *iface, UINT index, LCID lcid, ITypeInfo **ti) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + return IDispatchEx_GetTypeInfo(&doc->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI domdoc_GetIDsOfNames( - IXMLDOMDocument3 *iface, - REFIID riid, - LPOLESTR* rgszNames, - UINT cNames, - LCID lcid, - DISPID* rgDispId) +static HRESULT WINAPI domdoc_GetIDsOfNames(IXMLDOMDocument3 *iface, REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, - riid, rgszNames, cNames, lcid, rgDispId); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + return IDispatchEx_GetIDsOfNames(&doc->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); } -static HRESULT WINAPI domdoc_Invoke( - IXMLDOMDocument3 *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS* pDispParams, - VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, - UINT* puArgErr) +static HRESULT WINAPI domdoc_Invoke(IXMLDOMDocument3 *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, + UINT *puArgErr) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + return IDispatchEx_Invoke(&doc->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } -static HRESULT WINAPI domdoc_get_nodeName( - IXMLDOMDocument3 *iface, - BSTR* name ) +static HRESULT WINAPI domdoc_get_nodeName(IXMLDOMDocument3 *iface, BSTR *name) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - - TRACE("(%p)->(%p)\n", This, name); + TRACE("%p, %p.\n", iface, name); return return_bstr(L"#document", name); } - -static HRESULT WINAPI domdoc_get_nodeValue( - IXMLDOMDocument3 *iface, - VARIANT* value ) +static HRESULT WINAPI domdoc_get_nodeValue(IXMLDOMDocument3 *iface, VARIANT *value) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - - TRACE("(%p)->(%p)\n", This, value); + TRACE("%p, %p.\n", iface, value); - if(!value) - return E_INVALIDARG; - - V_VT(value) = VT_NULL; - V_BSTR(value) = NULL; /* tests show that we should do this */ - return S_FALSE; + return return_null_var(value); } - -static HRESULT WINAPI domdoc_put_nodeValue( - IXMLDOMDocument3 *iface, - VARIANT value) +static HRESULT WINAPI domdoc_put_nodeValue(IXMLDOMDocument3 *iface, VARIANT value) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + TRACE("%p, %s.\n", iface, debugstr_variant(&value)); + return E_FAIL; } - -static HRESULT WINAPI domdoc_get_nodeType( - IXMLDOMDocument3 *iface, - DOMNodeType* type ) +static HRESULT WINAPI domdoc_get_nodeType(IXMLDOMDocument3 *iface, DOMNodeType *type) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - - TRACE("(%p)->(%p)\n", This, type); + TRACE("%p, %p.\n", iface, type); *type = NODE_DOCUMENT; return S_OK; } - -static HRESULT WINAPI domdoc_get_parentNode( - IXMLDOMDocument3 *iface, - IXMLDOMNode** parent ) +static HRESULT WINAPI domdoc_get_parentNode(IXMLDOMDocument3 *iface, IXMLDOMNode **node) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - - TRACE("(%p)->(%p)\n", This, parent); + TRACE("%p, %p.\n", iface, node); - return node_get_parent(&This->node, parent); + return return_null_node(node); } - -static HRESULT WINAPI domdoc_get_childNodes( - IXMLDOMDocument3 *iface, - IXMLDOMNodeList** childList ) +static HRESULT WINAPI domdoc_get_childNodes(IXMLDOMDocument3 *iface, IXMLDOMNodeList **list) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%p)\n", This, childList); + TRACE("%p, %p.\n", iface, list); - return node_get_child_nodes(&This->node, childList); + return node_get_child_nodes(doc->node, list); } - -static HRESULT WINAPI domdoc_get_firstChild( - IXMLDOMDocument3 *iface, - IXMLDOMNode** firstChild ) +static HRESULT WINAPI domdoc_get_firstChild(IXMLDOMDocument3 *iface, IXMLDOMNode **node) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%p)\n", This, firstChild); + TRACE("%p, %p.\n", iface, node); - return node_get_first_child(&This->node, firstChild); + return node_get_first_child(doc->node, node); } - -static HRESULT WINAPI domdoc_get_lastChild( - IXMLDOMDocument3 *iface, - IXMLDOMNode** lastChild ) +static HRESULT WINAPI domdoc_get_lastChild(IXMLDOMDocument3 *iface, IXMLDOMNode **node) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%p)\n", This, lastChild); + TRACE("%p, %p.\n", iface, node); - return node_get_last_child(&This->node, lastChild); + return node_get_last_child(doc->node, node); } - -static HRESULT WINAPI domdoc_get_previousSibling( - IXMLDOMDocument3 *iface, - IXMLDOMNode** previousSibling ) +static HRESULT WINAPI domdoc_get_previousSibling(IXMLDOMDocument3 *iface, IXMLDOMNode **node) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + TRACE("%p, %p.\n", iface, node); - TRACE("(%p)->(%p)\n", This, previousSibling); - - return return_null_node(previousSibling); + return return_null_node(node); } - -static HRESULT WINAPI domdoc_get_nextSibling( - IXMLDOMDocument3 *iface, - IXMLDOMNode** nextSibling ) +static HRESULT WINAPI domdoc_get_nextSibling(IXMLDOMDocument3 *iface, IXMLDOMNode **node) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + TRACE("%p, %p.\n", iface, node); - TRACE("(%p)->(%p)\n", This, nextSibling); - - return return_null_node(nextSibling); + return return_null_node(node); } - -static HRESULT WINAPI domdoc_get_attributes( - IXMLDOMDocument3 *iface, - IXMLDOMNamedNodeMap** attributeMap ) +static HRESULT WINAPI domdoc_get_attributes(IXMLDOMDocument3 *iface, IXMLDOMNamedNodeMap **map) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - - TRACE("(%p)->(%p)\n", This, attributeMap); + TRACE("%p, %p.\n", iface, map); - return return_null_ptr((void**)attributeMap); + return return_null_ptr((void **)map); } - -static HRESULT WINAPI domdoc_insertBefore( - IXMLDOMDocument3 *iface, - IXMLDOMNode* newChild, - VARIANT refChild, - IXMLDOMNode** outNewChild ) +static HRESULT WINAPI domdoc_insertBefore(IXMLDOMDocument3 *iface, IXMLDOMNode* newChild, + VARIANT refChild, IXMLDOMNode** outNewChild) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - DOMNodeType type; - HRESULT hr; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%p %s %p)\n", This, newChild, debugstr_variant(&refChild), outNewChild); + TRACE("%p, %p, %s, %p.\n", iface, newChild, debugstr_variant(&refChild), outNewChild); - if (!newChild) return E_INVALIDARG; + return node_insert_before(doc->node, newChild, &refChild, outNewChild); +} - hr = IXMLDOMNode_get_nodeType(newChild, &type); - if (hr != S_OK) return hr; +static HRESULT WINAPI domdoc_replaceChild(IXMLDOMDocument3 *iface, IXMLDOMNode *newChild, + IXMLDOMNode* oldChild, IXMLDOMNode **outOldChild) +{ + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("new node type %d\n", type); - switch (type) - { - case NODE_ATTRIBUTE: - case NODE_DOCUMENT: - case NODE_CDATA_SECTION: - if (outNewChild) *outNewChild = NULL; - return E_FAIL; - default: - return node_insert_before(&This->node, newChild, &refChild, outNewChild); - } + TRACE("%p, %p, %p, %p.\n", iface, newChild, oldChild, outOldChild); + + return node_replace_child(doc->node, newChild, oldChild, outOldChild); } -static HRESULT WINAPI domdoc_replaceChild( - IXMLDOMDocument3 *iface, - IXMLDOMNode* newChild, - IXMLDOMNode* oldChild, - IXMLDOMNode** outOldChild) +static HRESULT WINAPI domdoc_removeChild(IXMLDOMDocument3 *iface, IXMLDOMNode *child, IXMLDOMNode **oldChild) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%p %p %p)\n", This, newChild, oldChild, outOldChild); + TRACE("%p, %p, %p.\n", iface, child, oldChild); - return node_replace_child(&This->node, newChild, oldChild, outOldChild); + return node_remove_child(doc->node, child, oldChild); } - -static HRESULT WINAPI domdoc_removeChild( - IXMLDOMDocument3 *iface, - IXMLDOMNode *child, - IXMLDOMNode **oldChild) +static HRESULT WINAPI domdoc_appendChild(IXMLDOMDocument3 *iface, IXMLDOMNode *child, IXMLDOMNode **outChild) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p %p)\n", This, child, oldChild); - return node_remove_child(&This->node, child, oldChild); -} + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + TRACE("%p, %p, %p.\n", iface, child, outChild); -static HRESULT WINAPI domdoc_appendChild( - IXMLDOMDocument3 *iface, - IXMLDOMNode *child, - IXMLDOMNode **outChild) -{ - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p %p)\n", This, child, outChild); - return node_append_child(&This->node, child, outChild); + return node_append_child(doc->node, child, outChild); } - -static HRESULT WINAPI domdoc_hasChildNodes( - IXMLDOMDocument3 *iface, - VARIANT_BOOL *ret) +static HRESULT WINAPI domdoc_hasChildNodes(IXMLDOMDocument3 *iface, VARIANT_BOOL *ret) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p)\n", This, ret); - return node_has_childnodes(&This->node, ret); -} + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + + TRACE("%p, %p.\n", iface, ret); + return node_has_childnodes(doc->node, ret); +} static HRESULT WINAPI domdoc_get_ownerDocument(IXMLDOMDocument3 *iface, IXMLDOMDocument **owner) { TRACE("%p, %p.\n", iface, owner); - if (!owner) - return E_INVALIDARG; - - *owner = NULL; - return S_FALSE; + return return_null_node((IXMLDOMNode **)owner); } -static HRESULT WINAPI domdoc_cloneNode( - IXMLDOMDocument3 *iface, - VARIANT_BOOL deep, - IXMLDOMNode** outNode) +static HRESULT WINAPI domdoc_cloneNode(IXMLDOMDocument3 *iface, VARIANT_BOOL deep, IXMLDOMNode **node) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - xmlNodePtr clone; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%d %p)\n", This, deep, outNode); + TRACE("%p, %d, %p.\n", iface, deep, node); - if (!outNode) + if (!node) return E_INVALIDARG; - *outNode = NULL; - - clone = xmlCopyNode((xmlNodePtr)get_doc(This), deep ? 1 : 2); - if (!clone) - return E_FAIL; - - clone->doc->_private = create_priv(); - priv_from_xmlDocPtr(clone->doc)->properties = copy_properties(This->properties); - xmldoc_release(clone->doc); - if (!(*outNode = (IXMLDOMNode*)create_domdoc(clone))) - return E_FAIL; - return S_OK; + return node_clone(doc->node, deep, node); } - -static HRESULT WINAPI domdoc_get_nodeTypeString( - IXMLDOMDocument3 *iface, - BSTR *p) +static HRESULT WINAPI domdoc_get_nodeTypeString(IXMLDOMDocument3 *iface, BSTR *p) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"document", p); } - -static HRESULT WINAPI domdoc_get_text( - IXMLDOMDocument3 *iface, - BSTR *p) +static HRESULT WINAPI domdoc_get_text(IXMLDOMDocument3 *iface, BSTR *p) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_text(&This->node, p); -} + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + TRACE("%p, %p.\n", iface, p); + + return node_get_text(doc->node, p); +} -static HRESULT WINAPI domdoc_put_text( - IXMLDOMDocument3 *iface, - BSTR text ) +static HRESULT WINAPI domdoc_put_text(IXMLDOMDocument3 *iface, BSTR text) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_w(text)); + TRACE("%p, %s.\n", iface, debugstr_w(text)); + return E_FAIL; } - -static HRESULT WINAPI domdoc_get_specified( - IXMLDOMDocument3 *iface, - VARIANT_BOOL* isSpecified ) +static HRESULT WINAPI domdoc_get_specified(IXMLDOMDocument3 *iface, VARIANT_BOOL *v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - FIXME("(%p)->(%p) stub!\n", This, isSpecified); - *isSpecified = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } - -static HRESULT WINAPI domdoc_get_definition( - IXMLDOMDocument3 *iface, - IXMLDOMNode** definitionNode ) +static HRESULT WINAPI domdoc_get_definition(IXMLDOMDocument3 *iface, IXMLDOMNode **node) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - FIXME("(%p)->(%p)\n", This, definitionNode); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } - -static HRESULT WINAPI domdoc_get_nodeTypedValue( - IXMLDOMDocument3 *iface, - VARIANT* v ) +static HRESULT WINAPI domdoc_get_nodeTypedValue(IXMLDOMDocument3 *iface, VARIANT *v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p)\n", This, v); + TRACE("%p, %p.\n", iface, v); + return return_null_var(v); } -static HRESULT WINAPI domdoc_put_nodeTypedValue( - IXMLDOMDocument3 *iface, - VARIANT typedValue ) +static HRESULT WINAPI domdoc_put_nodeTypedValue(IXMLDOMDocument3 *iface, VARIANT v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); + FIXME("%p, %s.\n", iface, debugstr_variant(&v)); + return E_NOTIMPL; } - -static HRESULT WINAPI domdoc_get_dataType( - IXMLDOMDocument3 *iface, - VARIANT* typename ) +static HRESULT WINAPI domdoc_get_dataType(IXMLDOMDocument3 *iface, VARIANT *v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p)\n", This, typename); - return return_null_var( typename ); -} + TRACE("%p, %p.\n", iface, v); + return return_null_var(v); +} -static HRESULT WINAPI domdoc_put_dataType( - IXMLDOMDocument3 *iface, - BSTR dataTypeName ) +static HRESULT WINAPI domdoc_put_dataType(IXMLDOMDocument3 *iface, BSTR p) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + FIXME("%p, %s.\n", iface, debugstr_w(p)); - FIXME("(%p)->(%s)\n", This, debugstr_w(dataTypeName)); - - if(!dataTypeName) + if (!p) return E_INVALIDARG; return E_FAIL; } -static int XMLCALL domdoc_get_xml_writecallback(void *ctx, const char *data, int len) +static HRESULT WINAPI domdoc_get_xml(IXMLDOMDocument3 *iface, BSTR *p) { - return xmlBufferAdd((xmlBufferPtr)ctx, (xmlChar*)data, len) == 0 ? len : 0; -} - -static HRESULT WINAPI domdoc_get_xml( - IXMLDOMDocument3 *iface, - BSTR* p) -{ - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - xmlSaveCtxtPtr ctxt; - xmlBufferPtr buf; - int options; - long ret; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - if(!p) + if (!p) return E_INVALIDARG; - *p = NULL; - - buf = xmlBufferCreate(); - if(!buf) - return E_OUTOFMEMORY; - - options = XML_SAVE_FORMAT | XML_SAVE_NO_DECL; - ctxt = xmlSaveToIO(domdoc_get_xml_writecallback, NULL, buf, "UTF-8", options); - - if(!ctxt) - { - xmlBufferFree(buf); - return E_OUTOFMEMORY; - } + return node_get_xml(doc->node, p); +} - ret = xmlSaveDoc(ctxt, get_doc(This)); - /* flushes on close */ - xmlSaveClose(ctxt); +static HRESULT WINAPI domdoc_transformNode(IXMLDOMDocument3 *iface, IXMLDOMNode *node, BSTR *p) +{ + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("%ld, len=%d\n", ret, xmlBufferLength(buf)); - if(ret != -1 && xmlBufferLength(buf) > 0) - { - BSTR content; + TRACE("%p, %p, %p.\n", iface, node, p); - content = bstr_from_xmlChar(xmlBufferContent(buf)); - content = EnsureCorrectEOL(content); + return node_transform_node(doc->node, node, p); +} - *p = content; - } - else - { - *p = SysAllocStringLen(NULL, 0); - } +static HRESULT WINAPI domdoc_selectNodes(IXMLDOMDocument3 *iface, BSTR p, IXMLDOMNodeList **list) +{ + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - xmlBufferFree(buf); + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), list); - return *p ? S_OK : E_OUTOFMEMORY; + return node_select_nodes(doc->node, p, list); } - -static HRESULT WINAPI domdoc_transformNode( - IXMLDOMDocument3 *iface, - IXMLDOMNode *node, - BSTR *p) +static HRESULT WINAPI domdoc_selectSingleNode(IXMLDOMDocument3 *iface, BSTR p, IXMLDOMNode **node) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p %p)\n", This, node, p); - return node_transform_node(&This->node, node, p); -} + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), node); -static HRESULT WINAPI domdoc_selectNodes( - IXMLDOMDocument3 *iface, - BSTR p, - IXMLDOMNodeList **outList) -{ - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); - return node_select_nodes(&This->node, p, outList); + return node_select_singlenode(doc->node, p, node); } - -static HRESULT WINAPI domdoc_selectSingleNode( - IXMLDOMDocument3 *iface, - BSTR p, - IXMLDOMNode **outNode) +static HRESULT WINAPI domdoc_get_parsed(IXMLDOMDocument3 *iface, VARIANT_BOOL *v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); - return node_select_singlenode(&This->node, p, outNode); -} - + FIXME("%p, %p stub!\n", iface, v); -static HRESULT WINAPI domdoc_get_parsed( - IXMLDOMDocument3 *iface, - VARIANT_BOOL* isParsed ) -{ - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - FIXME("(%p)->(%p) stub!\n", This, isParsed); - *isParsed = VARIANT_TRUE; + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domdoc_get_namespaceURI( - IXMLDOMDocument3 *iface, - BSTR* namespaceURI ) +static HRESULT WINAPI domdoc_get_namespaceURI(IXMLDOMDocument3 *iface, BSTR *uri) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p)\n", This, namespaceURI); - return return_null_bstr( namespaceURI ); + TRACE("%p, %p.\n", iface, uri); + + return return_null_bstr(uri); } -static HRESULT WINAPI domdoc_get_prefix( - IXMLDOMDocument3 *iface, - BSTR* prefix ) +static HRESULT WINAPI domdoc_get_prefix(IXMLDOMDocument3 *iface, BSTR *prefix) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p)\n", This, prefix); - return return_null_bstr( prefix ); -} + TRACE("%p, %p.\n", iface, prefix); + return return_null_bstr(prefix); +} -static HRESULT WINAPI domdoc_get_baseName( - IXMLDOMDocument3 *iface, - BSTR* name ) +static HRESULT WINAPI domdoc_get_baseName(IXMLDOMDocument3 *iface, BSTR *name) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p)\n", This, name); - return return_null_bstr( name ); -} + TRACE("%p, %p.\n", iface, name); + return return_null_bstr(name); +} -static HRESULT WINAPI domdoc_transformNodeToObject( - IXMLDOMDocument3 *iface, - IXMLDOMNode* stylesheet, - VARIANT output) +static HRESULT WINAPI domdoc_transformNodeToObject(IXMLDOMDocument3 *iface, + IXMLDOMNode *stylesheet, VARIANT output) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%p %s)\n", This, stylesheet, debugstr_variant(&output)); + TRACE("%p, %p, %s.\n", iface, stylesheet, debugstr_variant(&output)); switch (V_VT(&output)) { case VT_UNKNOWN: case VT_DISPATCH: { + IXMLDOMDocument *output_doc; ISequentialStream *stream; - IXMLDOMDocument *doc; HRESULT hr; BSTR str; @@ -1544,20 +795,20 @@ static HRESULT WINAPI domdoc_transformNodeToObject( /* FIXME: we're not supposed to query for document interface, should use IStream which we don't support currently. */ - if (IUnknown_QueryInterface(V_UNKNOWN(&output), &IID_IXMLDOMDocument, (void **)&doc) == S_OK) + if (IUnknown_QueryInterface(V_UNKNOWN(&output), &IID_IXMLDOMDocument, (void **)&output_doc) == S_OK) { VARIANT_BOOL b; - if (FAILED(hr = node_transform_node(&This->node, stylesheet, &str))) + if (FAILED(hr = node_transform_node(doc->node, stylesheet, &str))) return hr; - hr = IXMLDOMDocument_loadXML(doc, str, &b); + hr = IXMLDOMDocument_loadXML(output_doc, str, &b); SysFreeString(str); return hr; } else if (IUnknown_QueryInterface(V_UNKNOWN(&output), &IID_ISequentialStream, (void**)&stream) == S_OK) { - hr = node_transform_node_params(&This->node, stylesheet, NULL, stream, NULL); + hr = node_transform_node_params(doc->node, stylesheet, NULL, stream, NULL); ISequentialStream_Release(stream); return hr; } @@ -1575,132 +826,110 @@ static HRESULT WINAPI domdoc_transformNodeToObject( return E_NOTIMPL; } - -static HRESULT WINAPI domdoc_get_doctype( - IXMLDOMDocument3 *iface, - IXMLDOMDocumentType** doctype ) +static HRESULT WINAPI domdoc_get_doctype(IXMLDOMDocument3 *iface, IXMLDOMDocumentType **doctype) { - domdoc *This = impl_from_IXMLDOMDocument3(iface); - IXMLDOMNode *node; - xmlDtdPtr dtd; - HRESULT hr; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + struct domnode *node = NULL; - TRACE("(%p)->(%p)\n", This, doctype); + TRACE("%p, %p.\n", iface, doctype); - if (!doctype) return E_INVALIDARG; + if (!doctype) + return E_INVALIDARG; - *doctype = NULL; + LIST_FOR_EACH_ENTRY(node, &doc->node->children, struct domnode, entry) + { + if (node->type == NODE_DOCUMENT_TYPE) + { + return create_node(node, (IXMLDOMNode **)doctype); + } + } - dtd = xmlGetIntSubset(get_doc(This)); - if (!dtd) return S_FALSE; + return return_null_node((IXMLDOMNode **)doctype); +} - node = create_node((xmlNodePtr)dtd); - if (!node) return S_FALSE; +static HRESULT WINAPI domdoc_get_implementation(IXMLDOMDocument3 *iface, IXMLDOMImplementation **impl) +{ + TRACE("%p, %p.\n", iface, impl); - hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentType, (void**)doctype); - IXMLDOMNode_Release(node); + if (!impl) + return E_INVALIDARG; - return hr; + return create_dom_implementation(impl); } - -static HRESULT WINAPI domdoc_get_implementation( - IXMLDOMDocument3 *iface, - IXMLDOMImplementation** impl ) +static struct domnode * domdoc_get_document_element(struct domdoc *doc) { - domdoc *This = impl_from_IXMLDOMDocument3(iface); - - TRACE("(%p)->(%p)\n", This, impl); + struct domnode *node; - if(!impl) - return E_INVALIDARG; + LIST_FOR_EACH_ENTRY(node, &doc->node->children, struct domnode, entry) + { + if (node->type == NODE_ELEMENT) + return node; + } - return create_dom_implementation(impl); + return NULL; } -static HRESULT WINAPI domdoc_get_documentElement( - IXMLDOMDocument3 *iface, - IXMLDOMElement** DOMElement ) +static HRESULT WINAPI domdoc_get_documentElement(IXMLDOMDocument3 *iface, IXMLDOMElement **ret) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - IXMLDOMNode *element_node; - xmlNodePtr root; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + struct domnode *element; + IXMLDOMNode *node; HRESULT hr; - TRACE("(%p)->(%p)\n", This, DOMElement); + TRACE("%p, %p.\n", iface, ret); - if(!DOMElement) + if (!ret) return E_INVALIDARG; - *DOMElement = NULL; - - root = xmlDocGetRootElement( get_doc(This) ); - if ( !root ) - return S_FALSE; + *ret = NULL; - element_node = create_node( root ); - if(!element_node) return S_FALSE; - - hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (void**)DOMElement); - IXMLDOMNode_Release(element_node); + if ((element = domdoc_get_document_element(doc))) + { + if (SUCCEEDED(hr = create_node(element, &node))) + { + hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void **)ret); + IXMLDOMNode_Release(node); + return hr; + } + } - return hr; + return S_FALSE; } - -static HRESULT WINAPI domdoc_put_documentElement( - IXMLDOMDocument3 *iface, - IXMLDOMElement* DOMElement ) +static HRESULT WINAPI domdoc_putref_documentElement(IXMLDOMDocument3 *iface, IXMLDOMElement *element) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - IXMLDOMNode *elementNode; - xmlNodePtr oldRoot; - xmlDocPtr old_doc; - xmlnode *xmlNode; - int refcount = 0; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + struct domnode *current; + IXMLDOMNode *node; HRESULT hr; - TRACE("(%p)->(%p)\n", This, DOMElement); + TRACE("%p, %p.\n", iface, element); - hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode ); - if(FAILED(hr)) + if ((current = domdoc_get_document_element(doc))) + { + if (SUCCEEDED(hr = create_node(current, &node))) + { + hr = node_replace_child(doc->node, (IXMLDOMNode *)element, node, NULL); + IXMLDOMNode_Release(node); + } return hr; + } + else + { + hr = node_append_child(doc->node, (IXMLDOMNode *)element, NULL); + } - xmlNode = get_node_obj( elementNode ); - if(!xmlNode) return E_FAIL; - - if(!xmlNode->node->parent) - if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK) - WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node); - - old_doc = xmlNode->node->doc; - if (old_doc != get_doc(This)) - refcount = xmlnode_get_inst_cnt(xmlNode); - - /* old root is still orphaned by its document, update refcount from new root */ - if (refcount) xmldoc_add_refs(get_doc(This), refcount); - oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node); - if (refcount) xmldoc_release_refs(old_doc, refcount); - IXMLDOMNode_Release( elementNode ); - - if(oldRoot) - xmldoc_add_orphan(oldRoot->doc, oldRoot); - - return S_OK; + return hr; } - -static HRESULT WINAPI domdoc_createElement( - IXMLDOMDocument3 *iface, - BSTR tagname, - IXMLDOMElement** element ) +static HRESULT WINAPI domdoc_createElement(IXMLDOMDocument3 *iface, BSTR tagname, IXMLDOMElement **element) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); IXMLDOMNode *node; VARIANT type; HRESULT hr; - TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element); + TRACE("%p, %s, %p.\n", iface, debugstr_w(tagname), element); if (!element || !tagname) return E_INVALIDARG; @@ -1717,17 +946,13 @@ static HRESULT WINAPI domdoc_createElement( return hr; } - -static HRESULT WINAPI domdoc_createDocumentFragment( - IXMLDOMDocument3 *iface, - IXMLDOMDocumentFragment** frag ) +static HRESULT WINAPI domdoc_createDocumentFragment(IXMLDOMDocument3 *iface, IXMLDOMDocumentFragment **frag) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); IXMLDOMNode *node; VARIANT type; HRESULT hr; - TRACE("(%p)->(%p)\n", This, frag); + TRACE("%p, %p.\n", iface, frag); if (!frag) return E_INVALIDARG; @@ -1746,18 +971,13 @@ static HRESULT WINAPI domdoc_createDocumentFragment( return hr; } - -static HRESULT WINAPI domdoc_createTextNode( - IXMLDOMDocument3 *iface, - BSTR data, - IXMLDOMText** text ) +static HRESULT WINAPI domdoc_createTextNode(IXMLDOMDocument3 *iface, BSTR data, IXMLDOMText **text) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); IXMLDOMNode *node; VARIANT type; HRESULT hr; - TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text); + TRACE("%p, %s, %p.\n", iface, debugstr_w(data), text); if (!text) return E_INVALIDARG; @@ -1777,18 +997,13 @@ static HRESULT WINAPI domdoc_createTextNode( return hr; } - -static HRESULT WINAPI domdoc_createComment( - IXMLDOMDocument3 *iface, - BSTR data, - IXMLDOMComment** comment ) +static HRESULT WINAPI domdoc_createComment(IXMLDOMDocument3 *iface, BSTR data, IXMLDOMComment **comment) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + IXMLDOMNode *node; VARIANT type; HRESULT hr; - IXMLDOMNode *node; - TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment); + TRACE("%p, %s, %p.\n", iface, debugstr_w(data), comment); if (!comment) return E_INVALIDARG; @@ -1808,18 +1023,13 @@ static HRESULT WINAPI domdoc_createComment( return hr; } - -static HRESULT WINAPI domdoc_createCDATASection( - IXMLDOMDocument3 *iface, - BSTR data, - IXMLDOMCDATASection** cdata ) +static HRESULT WINAPI domdoc_createCDATASection(IXMLDOMDocument3 *iface, BSTR data, IXMLDOMCDATASection **cdata) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); IXMLDOMNode *node; VARIANT type; HRESULT hr; - TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata); + TRACE("%p, %s, %p.\n", iface, debugstr_w(data), cdata); if (!cdata) return E_INVALIDARG; @@ -1839,52 +1049,23 @@ static HRESULT WINAPI domdoc_createCDATASection( return hr; } - -static HRESULT WINAPI domdoc_createProcessingInstruction( - IXMLDOMDocument3 *iface, - BSTR target, - BSTR data, - IXMLDOMProcessingInstruction** pi ) +static HRESULT WINAPI domdoc_createProcessingInstruction(IXMLDOMDocument3 *iface, + BSTR target, BSTR data, IXMLDOMProcessingInstruction **pi) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - IXMLDOMNode *node; - VARIANT type; - HRESULT hr; - - TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi); - - if (!pi) return E_INVALIDARG; - - *pi = NULL; - - V_VT(&type) = VT_I1; - V_I1(&type) = NODE_PROCESSING_INSTRUCTION; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - hr = IXMLDOMDocument3_createNode(iface, type, target, NULL, &node); - if (hr == S_OK) - { - /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */ - hr = dom_pi_put_xml_decl(node, data); - if (SUCCEEDED(hr)) - hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi); - IXMLDOMNode_Release(node); - } + TRACE("%p, %s, %s, %p.\n", iface, debugstr_w(target), debugstr_w(data), pi); - return hr; + return create_pi_node(doc->node, target, data, pi); } - -static HRESULT WINAPI domdoc_createAttribute( - IXMLDOMDocument3 *iface, - BSTR name, - IXMLDOMAttribute** attribute ) +static HRESULT WINAPI domdoc_createAttribute(IXMLDOMDocument3 *iface, BSTR name, IXMLDOMAttribute **attribute) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); IXMLDOMNode *node; VARIANT type; HRESULT hr; - TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute); + TRACE("%p, %s, %p.\n", iface, debugstr_w(name), attribute); if (!attribute || !name) return E_INVALIDARG; @@ -1901,18 +1082,13 @@ static HRESULT WINAPI domdoc_createAttribute( return hr; } - -static HRESULT WINAPI domdoc_createEntityReference( - IXMLDOMDocument3 *iface, - BSTR name, - IXMLDOMEntityReference** entityref ) +static HRESULT WINAPI domdoc_createEntityReference(IXMLDOMDocument3 *iface, BSTR name, IXMLDOMEntityReference **entityref) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); IXMLDOMNode *node; VARIANT type; HRESULT hr; - TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref); + TRACE("%p, %s, %p.\n", iface, debugstr_w(name), entityref); if (!entityref) return E_INVALIDARG; @@ -1931,76 +1107,13 @@ static HRESULT WINAPI domdoc_createEntityReference( return hr; } -xmlChar* tagName_to_XPath(const BSTR tagName) -{ - xmlChar *query, *tmp; - static const xmlChar everything[] = "/descendant::node()"; - static const xmlChar mod_pre[] = "*[local-name()='"; - static const xmlChar mod_post[] = "']"; - static const xmlChar prefix[] = "descendant::"; - const WCHAR *tokBegin, *tokEnd; - int len; - - /* Special case - empty tagname - means select all nodes, - except document itself. */ - if (!*tagName) - return xmlStrdup(everything); - - query = xmlStrdup(prefix); - - tokBegin = tagName; - while (tokBegin && *tokBegin) - { - switch (*tokBegin) - { - case '/': - query = xmlStrcat(query, BAD_CAST "/"); - ++tokBegin; - break; - case '*': - query = xmlStrcat(query, BAD_CAST "*"); - ++tokBegin; - break; - default: - query = xmlStrcat(query, mod_pre); - tokEnd = tokBegin; - while (*tokEnd && *tokEnd != '/') - ++tokEnd; - len = WideCharToMultiByte(CP_UTF8, 0, tokBegin, tokEnd-tokBegin, NULL, 0, NULL, NULL); - tmp = xmlMalloc(len); - WideCharToMultiByte(CP_UTF8, 0, tokBegin, tokEnd-tokBegin, (char*)tmp, len, NULL, NULL); - query = xmlStrncat(query, tmp, len); - xmlFree(tmp); - tokBegin = tokEnd; - query = xmlStrcat(query, mod_post); - } - } - - return query; -} - -static HRESULT WINAPI domdoc_getElementsByTagName( - IXMLDOMDocument3 *iface, - BSTR tagName, - IXMLDOMNodeList** resultList ) +static HRESULT WINAPI domdoc_getElementsByTagName(IXMLDOMDocument3 *iface, BSTR name, IXMLDOMNodeList **list) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - xmlChar *query; - HRESULT hr; - BOOL XPath; - - TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList); - - if (!tagName || !resultList) return E_INVALIDARG; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - XPath = This->properties->XPath; - This->properties->XPath = TRUE; - query = tagName_to_XPath(tagName); - hr = create_selection((xmlNodePtr)get_doc(This), query, resultList); - xmlFree(query); - This->properties->XPath = XPath; + TRACE("%p, %s, %p.\n", iface, debugstr_w(name), list); - return hr; + return node_get_elements_by_tagname(doc->node, name, list); } static bool get_node_type_from_typestring(const WCHAR *name, DOMNodeType *type) @@ -2045,155 +1158,78 @@ static HRESULT get_node_type(const VARIANT *v, DOMNodeType * type) return S_OK; } -static HRESULT WINAPI domdoc_createNode( - IXMLDOMDocument3 *iface, - VARIANT Type, - BSTR name, - BSTR namespaceURI, - IXMLDOMNode** node ) +static HRESULT WINAPI domdoc_createNode(IXMLDOMDocument3 *iface, VARIANT type, BSTR name, + BSTR uri, IXMLDOMNode **node) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + struct domnode *domnode; DOMNodeType node_type; - xmlNodePtr xmlnode; - xmlChar *xml_name, *href; HRESULT hr; - TRACE("(%p)->(%s %s %s %p)\n", This, debugstr_variant(&Type), debugstr_w(name), debugstr_w(namespaceURI), node); - - if(!node) return E_INVALIDARG; - - hr = get_node_type(&Type, &node_type); - if(FAILED(hr)) return hr; - - TRACE("node_type %d\n", node_type); - - /* exit earlier for types that need name */ - switch(node_type) - { - case NODE_ELEMENT: - case NODE_ATTRIBUTE: - case NODE_ENTITY_REFERENCE: - case NODE_PROCESSING_INSTRUCTION: - if (!name || *name == 0) return E_FAIL; - break; - default: - break; - } - - xml_name = xmlchar_from_wchar(name); - /* prevent empty href from being allocated */ - href = namespaceURI ? xmlchar_from_wchar(namespaceURI) : NULL; - - switch(node_type) - { - case NODE_ELEMENT: - { - xmlChar *local, *prefix; - - local = xmlSplitQName2(xml_name, &prefix); - - xmlnode = xmlNewDocNode(get_doc(This), NULL, local ? local : xml_name, NULL); + TRACE("%p, %s, %s, %s, %p.\n", iface, debugstr_variant(&type), debugstr_w(name), debugstr_w(uri), node); - /* allow creating the default namespace xmlns= */ - if (local || (href && *href)) - { - xmlNsPtr ns = xmlNewNs(xmlnode, href, prefix); - xmlSetNs(xmlnode, ns); - } + if (!node) + return E_INVALIDARG; - xmlFree(local); - xmlFree(prefix); + if (FAILED(hr = get_node_type(&type, &node_type))) + return hr; - break; - } - case NODE_ATTRIBUTE: + switch (node_type) { - xmlChar *local, *prefix; - - local = xmlSplitQName2(xml_name, &prefix); - - xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), local ? local : xml_name, NULL); - - if (local || (href && *href)) - { - /* we need a floating namespace here, it can't be created linked to attribute from - a start */ - xmlNsPtr ns = xmlNewNs(NULL, href, prefix); - xmlSetNs(xmlnode, ns); - } + /* Check if we need a name */ + case NODE_ELEMENT: + case NODE_ATTRIBUTE: + case NODE_ENTITY_REFERENCE: + case NODE_PROCESSING_INSTRUCTION: - xmlFree(local); - xmlFree(prefix); + if (!name || *name == 0) + return E_FAIL; + break; - break; - } - case NODE_TEXT: - xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL); - break; - case NODE_CDATA_SECTION: - xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0); - break; - case NODE_ENTITY_REFERENCE: - xmlnode = xmlNewReference(get_doc(This), xml_name); - break; - case NODE_PROCESSING_INSTRUCTION: - xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL); - break; - case NODE_COMMENT: - xmlnode = xmlNewDocComment(get_doc(This), NULL); - break; - case NODE_DOCUMENT_FRAGMENT: - xmlnode = xmlNewDocFragment(get_doc(This)); - break; - /* unsupported types */ - case NODE_DOCUMENT: - case NODE_DOCUMENT_TYPE: - case NODE_ENTITY: - case NODE_NOTATION: - free(xml_name); - return E_INVALIDARG; - default: - FIXME("unhandled node type %d\n", node_type); - xmlnode = NULL; - break; + /* Unsupported types */ + case NODE_DOCUMENT: + case NODE_DOCUMENT_TYPE: + case NODE_ENTITY: + case NODE_NOTATION: + return E_INVALIDARG; + + default: + break; } - *node = create_node(xmlnode); - free(xml_name); - free(href); + *node = NULL; - if(*node) + if (FAILED(hr = domnode_create(node_type, name, SysStringLen(name), uri, SysStringLen(uri), + doc->node, &domnode))) { - TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode); - xmldoc_add_orphan(xmlnode->doc, xmlnode); - return S_OK; + return hr; } - return E_FAIL; + return create_node(domnode, node); } -static HRESULT WINAPI domdoc_nodeFromID( - IXMLDOMDocument3 *iface, - BSTR idString, - IXMLDOMNode** node ) +static HRESULT WINAPI domdoc_nodeFromID(IXMLDOMDocument3 *iface, BSTR id, IXMLDOMNode **node) { - domdoc *This = impl_from_IXMLDOMDocument3(iface); - FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node); + FIXME("%p, %s, %p.\n", iface, debugstr_w(id), node); + return E_NOTIMPL; } static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len) { - domdoc *This = obj; - xmlDocPtr xmldoc; + struct domnode *node = NULL; + ISequentialStream *stream; + domdoc *doc = obj; + HRESULT hr; - xmldoc = doparse(This, ptr, len, XML_CHAR_ENCODING_NONE); - if(xmldoc) { - xmldoc->_private = create_priv(); - return attach_xmldoc(This, xmldoc); - } + stream_wrapper_create(ptr, len, &stream); + hr = parse_stream(stream, false, doc->node->properties->preserving, &node); + ISequentialStream_Release(stream); - return E_FAIL; + if (hr == S_OK) + attach_doc_node(doc, node); + + return hr; } static HRESULT domdoc_load_moniker(domdoc *This, IMoniker *mon) @@ -2208,25 +1244,22 @@ static HRESULT domdoc_load_moniker(domdoc *This, IMoniker *mon) return detach_bsc(bsc); } -static HRESULT WINAPI domdoc_load( - IXMLDOMDocument3 *iface, - VARIANT source, - VARIANT_BOOL* isSuccessful ) +static HRESULT WINAPI domdoc_load(IXMLDOMDocument3 *iface, VARIANT source, VARIANT_BOOL *result) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + ISequentialStream *stream = NULL; LPWSTR filename = NULL; HRESULT hr = S_FALSE; - xmlDocPtr xmldoc; + struct domnode *node; - TRACE("(%p)->(%s)\n", This, debugstr_variant(&source)); + TRACE("%p, %s, %p.\n", iface, debugstr_variant(&source), result); - if (!isSuccessful) + if (!result) return E_POINTER; - *isSuccessful = VARIANT_FALSE; - assert( &This->node ); + *result = VARIANT_FALSE; - switch( V_VT(&source) ) + switch (V_VT(&source)) { case VT_BSTR: filename = V_BSTR(&source); @@ -2240,13 +1273,14 @@ static HRESULT WINAPI domdoc_load( SAFEARRAY *psa = V_ARRAY(&source); char *str; LONG len; - UINT dim = SafeArrayGetDim(psa); + UINT dim; + dim = SafeArrayGetDim(psa); switch (dim) { case 0: ERR("SAFEARRAY == NULL\n"); - hr = This->error = E_INVALIDARG; + hr = doc->error = E_INVALIDARG; break; case 1: /* Only takes UTF-8 strings. @@ -2254,58 +1288,65 @@ static HRESULT WINAPI domdoc_load( hr = SafeArrayAccessData(psa, (void**)&str); if (FAILED(hr)) { - This->error = hr; + doc->error = hr; WARN("failed to access array data, hr %#lx.\n", hr); break; } SafeArrayGetUBound(psa, 1, &len); - if ((xmldoc = doparse(This, str, ++len, XML_CHAR_ENCODING_UTF8))) + if (SUCCEEDED(hr = stream_wrapper_create(str, len + 1, &stream))) { - hr = This->error = S_OK; - *isSuccessful = VARIANT_TRUE; - TRACE("parsed document %p\n", xmldoc); + hr = doc->error = domdoc_load_from_stream(doc, stream); + ISequentialStream_Release(stream); + } + SafeArrayUnaccessData(psa); + + if (hr == S_OK) + { + hr = doc->error = S_OK; + *result = VARIANT_TRUE; } else { - This->error = E_FAIL; + doc->error = E_FAIL; TRACE("failed to parse document\n"); } SafeArrayUnaccessData(psa); - if(xmldoc) - { - xmldoc->_private = create_priv(); - return attach_xmldoc(This, xmldoc); - } - break; + return doc->error == S_OK ? S_OK : S_FALSE; default: FIXME("unhandled SAFEARRAY dim: %d\n", dim); - hr = This->error = E_NOTIMPL; + hr = doc->error = E_NOTIMPL; } } break; case VT_UNKNOWN: { - ISequentialStream *stream = NULL; IXMLDOMDocument3 *newdoc = NULL; if (!V_UNKNOWN(&source)) return E_INVALIDARG; - hr = IUnknown_QueryInterface(V_UNKNOWN(&source), &IID_IXMLDOMDocument3, (void**)&newdoc); - if(hr == S_OK) + hr = IUnknown_QueryInterface(V_UNKNOWN(&source), &IID_IXMLDOMDocument3, (void **)&newdoc); + if (hr == S_OK) { - if(newdoc) + if (newdoc) { - domdoc *newDoc = impl_from_IXMLDOMDocument3( newdoc ); + struct domnode *node = get_node_obj((IXMLDOMNode *)newdoc); + struct domnode *cloned; + + hr = node_clone_domnode(node, true, &cloned); + IXMLDOMDocument3_Release(newdoc); - xmldoc = xmlCopyDoc(get_doc(newDoc), 1); - xmldoc->_private = create_priv(); - hr = attach_xmldoc(This, xmldoc); + if (FAILED(hr)) + { + WARN("Failed to clone a document, hr %#lx.\n", hr); + return hr; + } - if(SUCCEEDED(hr)) - *isSuccessful = VARIANT_TRUE; + attach_doc_node(doc, cloned); + if (SUCCEEDED(hr)) + *result = VARIANT_TRUE; return hr; } @@ -2317,9 +1358,9 @@ static HRESULT WINAPI domdoc_load( if (hr == S_OK) { - hr = This->error = domdoc_load_from_stream(This, stream); + hr = doc->error = domdoc_load_from_stream(doc, stream); if (hr == S_OK) - *isSuccessful = VARIANT_TRUE; + *result = VARIANT_TRUE; ISequentialStream_Release(stream); return hr; } @@ -2331,46 +1372,50 @@ static HRESULT WINAPI domdoc_load( FIXME("VT type not supported (%d)\n", V_VT(&source)); } - if ( filename ) + if (filename) { IUri *uri = NULL; IMoniker *mon; - if (This->properties->uri) + if (doc->node->properties->uri) { - IUri_Release(This->properties->uri); - This->properties->uri = NULL; + IUri_Release(doc->node->properties->uri); + doc->node->properties->uri = NULL; } - hr = create_uri(This->base_uri, filename, &uri); + hr = create_uri(doc->base_uri, filename, &uri); if (SUCCEEDED(hr)) hr = CreateURLMonikerEx2(NULL, uri, &mon, 0); - if ( SUCCEEDED(hr) ) + if (SUCCEEDED(hr)) { - hr = domdoc_load_moniker( This, mon ); + hr = domdoc_load_moniker(doc, mon); IMoniker_Release(mon); } if (SUCCEEDED(hr)) { - get_doc(This)->name = (char *)xmlchar_from_wcharn(filename, -1, TRUE); - This->properties->uri = uri; - hr = This->error = S_OK; - *isSuccessful = VARIANT_TRUE; + //get_doc(doc)->name = (char *)xmlchar_from_wcharn(filename, -1, TRUE); + doc->node->properties->uri = uri; + hr = doc->error = S_OK; + *result = VARIANT_TRUE; } else { if (uri) IUri_Release(uri); - This->error = E_FAIL; + doc->error = E_FAIL; } } - if(!filename || FAILED(hr)) { - xmldoc = xmlNewDoc(NULL); - xmldoc->_private = create_priv(); - hr = attach_xmldoc(This, xmldoc); - if(SUCCEEDED(hr)) + if (!filename || FAILED(hr)) + { + hr = domnode_create(NODE_DOCUMENT, NULL, 0, NULL, 0, NULL, &node); + if (node) + { + node->properties = domdoc_create_properties(doc->node->properties->version); + attach_doc_node(doc, node); + } + if (SUCCEEDED(hr)) hr = S_FALSE; } @@ -2379,13 +1424,9 @@ static HRESULT WINAPI domdoc_load( return hr; } - -static HRESULT WINAPI domdoc_get_readyState( - IXMLDOMDocument3 *iface, - LONG *value ) +static HRESULT WINAPI domdoc_get_readyState(IXMLDOMDocument3 *iface, LONG *value) { - domdoc *This = impl_from_IXMLDOMDocument3(iface); - FIXME("stub! (%p)->(%p)\n", This, value); + FIXME("%p, %p.\n", iface, value); if (!value) return E_INVALIDARG; @@ -2394,470 +1435,329 @@ static HRESULT WINAPI domdoc_get_readyState( return S_OK; } - -static HRESULT WINAPI domdoc_get_parseError( - IXMLDOMDocument3 *iface, - IXMLDOMParseError** errorObj ) +static HRESULT WINAPI domdoc_get_parseError(IXMLDOMDocument3 *iface, IXMLDOMParseError **obj) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); BSTR error_string = NULL; - FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj); + FIXME("%p, %p semi-stub\n", iface, obj); - if(This->error) + if (doc->error) error_string = SysAllocString(L"error"); - *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0); - if(!*errorObj) return E_OUTOFMEMORY; + *obj = create_parseError(doc->error, NULL, error_string, NULL, 0, 0, 0); + if (!*obj) return E_OUTOFMEMORY; return S_OK; } - -static HRESULT WINAPI domdoc_get_url( - IXMLDOMDocument3 *iface, - BSTR* url ) +static HRESULT WINAPI domdoc_get_url(IXMLDOMDocument3 *iface, BSTR *url) { - domdoc *This = impl_from_IXMLDOMDocument3(iface); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%p)\n", This, url); + TRACE("%p, %p.\n", iface, url); if (!url) return E_INVALIDARG; - if (!This->properties->uri) + if (!doc->node->properties->uri) return return_null_bstr(url); - return IUri_GetPropertyBSTR(This->properties->uri, Uri_PROPERTY_DISPLAY_URI, url, 0); + return IUri_GetPropertyBSTR(doc->node->properties->uri, Uri_PROPERTY_DISPLAY_URI, url, 0); } - -static HRESULT WINAPI domdoc_get_async( - IXMLDOMDocument3 *iface, - VARIANT_BOOL* isAsync ) +static HRESULT WINAPI domdoc_get_async(IXMLDOMDocument3 *iface, VARIANT_BOOL *v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + + TRACE("%p, %p.\n", iface, v); - TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async); - *isAsync = This->async; + *v = doc->async; return S_OK; } - -static HRESULT WINAPI domdoc_put_async( - IXMLDOMDocument3 *iface, - VARIANT_BOOL isAsync ) +static HRESULT WINAPI domdoc_put_async(IXMLDOMDocument3 *iface, VARIANT_BOOL v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%d)\n", This, isAsync); - This->async = isAsync; + TRACE("%p, %d.\n", iface, v); + + doc->async = v; return S_OK; } - -static HRESULT WINAPI domdoc_abort( - IXMLDOMDocument3 *iface ) +static HRESULT WINAPI domdoc_abort(IXMLDOMDocument3 *iface) { - domdoc *This = impl_from_IXMLDOMDocument3(iface); - FIXME("%p\n", This); + FIXME("%p\n", iface); + return E_NOTIMPL; } -/* don't rely on data to be in BSTR format, treat it as WCHAR string */ -static HRESULT WINAPI domdoc_loadXML( - IXMLDOMDocument3 *iface, - BSTR data, - VARIANT_BOOL* isSuccessful ) +/* Don't rely on data to be in BSTR format, treat it as WCHAR string. */ +static HRESULT WINAPI domdoc_loadXML(IXMLDOMDocument3 *iface, BSTR data, VARIANT_BOOL *result) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - xmlDocPtr xmldoc = NULL; - HRESULT hr = S_FALSE, hr2; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + struct domnode *node; + HRESULT hr = E_FAIL; + VARIANT_BOOL b; + + TRACE("%p, %s, %p.\n", iface, debugstr_w(data), result); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), isSuccessful ); + if (!result) result = &b; - assert ( &This->node ); + *result = VARIANT_FALSE; - if ( isSuccessful ) + if (data && *data) { - *isSuccessful = VARIANT_FALSE; + ISequentialStream *stream; + WCHAR *ptr = data; - if (data) + /* Skip leading spaces. */ + if (doc->node->properties->version == MSXML_DEFAULT || doc->node->properties->version == MSXML26) { - WCHAR *ptr = data; - - /* skip leading spaces if needed */ - if (This->properties->version == MSXML_DEFAULT || This->properties->version == MSXML26) - while (*ptr && iswspace(*ptr)) ptr++; - - xmldoc = doparse(This, (char*)ptr, lstrlenW(ptr)*sizeof(WCHAR), XML_CHAR_ENCODING_UTF16LE); - if ( !xmldoc ) - { - This->error = E_FAIL; - TRACE("failed to parse document\n"); - } - else - { - hr = This->error = S_OK; - *isSuccessful = VARIANT_TRUE; - TRACE("parsed document %p\n", xmldoc); - } + while (*ptr && iswspace(*ptr)) ptr++; } - } - if(!xmldoc) - xmldoc = xmlNewDoc(NULL); - xmldoc->_private = create_priv(); - hr2 = attach_xmldoc(This, xmldoc); - if( FAILED(hr2) ) - hr = hr2; + if (SUCCEEDED(hr = stream_wrapper_create(ptr, lstrlenW(ptr) * sizeof(WCHAR), &stream))) + { + hr = parse_stream(stream, true, doc->node->properties->preserving, &node); + ISequentialStream_Release(stream); + } - return hr; -} + if (hr == S_OK) + { + attach_doc_node(doc, node); + *result = VARIANT_TRUE; + } -static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer, int len) -{ - DWORD written = -1; + doc->error = hr; - if(!WriteFile(ctx, buffer, len, &written, NULL)) - { - WARN("write error\n"); - return -1; + if (FAILED(hr)) hr = S_FALSE; } else - return written; -} - -static int XMLCALL domdoc_save_closecallback(void *ctx) -{ - return CloseHandle(ctx) ? 0 : -1; -} - -static int XMLCALL domdoc_stream_save_writecallback(void *ctx, const char *buffer, int len) -{ - ULONG written = 0; - HRESULT hr; - - hr = IStream_Write((IStream*)ctx, buffer, len, &written); - TRACE("hr %#lx, %p, %d, %lu.\n", hr, buffer, len, written); - if (hr != S_OK) { - WARN("stream write error, hr %#lx.\n", hr); - return -1; + domnode_create(NODE_DOCUMENT, NULL, 0, NULL, 0, NULL, &node); + node->properties = domdoc_create_properties(doc->node->properties->version); + attach_doc_node(doc, node); + + hr = S_FALSE; } - else - return len; -} -static int XMLCALL domdoc_stream_save_closecallback(void *ctx) -{ - IStream_Release((IStream*)ctx); - return 0; + return hr; } -static char *xmldoc_encoding(IXMLDOMDocument3 *doc) +static HRESULT WINAPI domdoc_save(IXMLDOMDocument3 *iface, VARIANT dest) { + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + IStream *stream; HRESULT hr; - IXMLDOMNode *node; - char *encoding = NULL; - hr = IXMLDOMDocument3_get_firstChild(doc, &node); - if (hr == S_OK) - { - DOMNodeType type; - - hr = IXMLDOMNode_get_nodeType(node, &type); - if (hr == S_OK && type == NODE_PROCESSING_INSTRUCTION) - { - IXMLDOMProcessingInstruction *pi; - IXMLDOMNode *item; - IXMLDOMNamedNodeMap *node_map; + TRACE("%p, %s.\n", iface, debugstr_variant(&dest)); - hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void **)&pi); - if (hr == S_OK) + switch (V_VT(&dest)) + { + case VT_UNKNOWN: { - hr = IXMLDOMNode_get_attributes(node, &node_map); + IUnknown *unk = V_UNKNOWN(&dest); + IXMLDOMDocument3 *document; + + hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMDocument3, (void **)&document); if (hr == S_OK) { - BSTR bstr; + VARIANT_BOOL success; + BSTR xml; - bstr = SysAllocString(L"encoding"); - hr = IXMLDOMNamedNodeMap_getNamedItem(node_map, bstr, &item); - SysFreeString(bstr); + hr = IXMLDOMDocument3_get_xml(iface, &xml); if (hr == S_OK) { - VARIANT var; - - hr = IXMLDOMNode_get_nodeValue(item, &var); - if (hr == S_OK) - { - if (V_VT(&var) == VT_BSTR) - encoding = (char *)xmlchar_from_wchar(V_BSTR(&var)); - - VariantClear(&var); - } + hr = IXMLDOMDocument3_loadXML(document, xml, &success); + SysFreeString(xml); } - IXMLDOMNamedNodeMap_Release(node_map); - } - - IXMLDOMProcessingInstruction_Release(pi); - } - } - - IXMLDOMNode_Release(node); - } - - if (!encoding && (encoding = malloc(sizeof("UTF-8")))) - strcpy(encoding, "UTF-8"); - - return encoding; -} - -static HRESULT WINAPI domdoc_save( - IXMLDOMDocument3 *iface, - VARIANT destination ) -{ - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - xmlSaveCtxtPtr ctx = NULL; - HRESULT ret = S_OK; - - TRACE("(%p)->(%s)\n", This, debugstr_variant(&destination)); - - switch (V_VT(&destination)) - { - case VT_UNKNOWN: - { - IUnknown *pUnk = V_UNKNOWN(&destination); - IXMLDOMDocument3 *document; - IStream *stream; - - ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument3, (void**)&document); - if(ret == S_OK) - { - VARIANT_BOOL success; - BSTR xml; - - ret = IXMLDOMDocument3_get_xml(iface, &xml); - if(ret == S_OK) - { - ret = IXMLDOMDocument3_loadXML(document, xml, &success); - SysFreeString(xml); + IXMLDOMDocument3_Release(document); + return hr; } - IXMLDOMDocument3_Release(document); - return ret; - } - - ret = IUnknown_QueryInterface(pUnk, &IID_IStream, (void**)&stream); - if(ret == S_OK) - { - char *encoding = xmldoc_encoding(iface); - - TRACE("using encoding %s\n", encoding ? debugstr_a(encoding) : "default"); - ctx = xmlSaveToIO(domdoc_stream_save_writecallback, - domdoc_stream_save_closecallback, stream, encoding, XML_SAVE_NO_DECL); - free(encoding); - - if(!ctx) + hr = IUnknown_QueryInterface(unk, &IID_IStream, (void **)&stream); + if (hr == S_OK) { + hr = node_save(doc->node, stream); IStream_Release(stream); - return E_FAIL; } } - } - break; + break; case VT_BSTR: case VT_BSTR | VT_BYREF: { - char *encoding; - /* save with file path */ - HANDLE handle = CreateFileW( (V_VT(&destination) & VT_BYREF)? *V_BSTRREF(&destination) : V_BSTR(&destination), - GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); - if( handle == INVALID_HANDLE_VALUE ) - { - WARN("failed to create file\n"); - return E_FAIL; - } + const WCHAR *path; - encoding = xmldoc_encoding(iface); - TRACE("using encoding %s\n", encoding ? debugstr_a(encoding) : "default"); - ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback, - handle, encoding, XML_SAVE_NO_DECL); - free(encoding); + path = V_VT(&dest) & VT_BYREF ? *V_BSTRREF(&dest) : V_BSTR(&dest); - if (!ctx) + hr = SHCreateStreamOnFileEx(path, STGM_CREATE | STGM_WRITE, FILE_ATTRIBUTE_NORMAL, TRUE, NULL, &stream); + if (FAILED(hr)) { - CloseHandle(handle); - return E_FAIL; + WARN("Failed to create a file stream, hr %#lx.\n", hr); + return hr; } + + hr = node_save(doc->node, stream); + IStream_Release(stream); } break; default: - FIXME("Unhandled VARIANT: %s\n", debugstr_variant(&destination)); + FIXME("Unhandled destination type %s.\n", debugstr_variant(&dest)); return S_FALSE; } - if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE; - - /* will release resources through close callback */ - xmlSaveClose(ctx); - - return ret; + return hr; } -static HRESULT WINAPI domdoc_get_validateOnParse( - IXMLDOMDocument3 *iface, - VARIANT_BOOL* isValidating ) +static HRESULT WINAPI domdoc_get_validateOnParse(IXMLDOMDocument3 *iface, VARIANT_BOOL *v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p: %d)\n", This, isValidating, This->properties->validating); - *isValidating = This->properties->validating; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + struct domnode *node = doc->node; + + TRACE("%p, %p.\n", iface, v); + + *v = node->properties->validating; return S_OK; } - -static HRESULT WINAPI domdoc_put_validateOnParse( - IXMLDOMDocument3 *iface, - VARIANT_BOOL isValidating ) +static HRESULT WINAPI domdoc_put_validateOnParse(IXMLDOMDocument3 *iface, VARIANT_BOOL v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%d)\n", This, isValidating); - This->properties->validating = isValidating; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + struct domnode *node = doc->node; + + TRACE("%p, %d.\n", iface, v); + + node->properties->validating = v; return S_OK; } - -static HRESULT WINAPI domdoc_get_resolveExternals( - IXMLDOMDocument3 *iface, - VARIANT_BOOL* isResolving ) +static HRESULT WINAPI domdoc_get_resolveExternals(IXMLDOMDocument3 *iface, VARIANT_BOOL *v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving); - *isResolving = This->resolving; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + + TRACE("%p, %p.\n", iface, v); + + *v = doc->resolving; return S_OK; } - -static HRESULT WINAPI domdoc_put_resolveExternals( - IXMLDOMDocument3 *iface, - VARIANT_BOOL isResolving ) +static HRESULT WINAPI domdoc_put_resolveExternals(IXMLDOMDocument3 *iface, VARIANT_BOOL v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%d)\n", This, isResolving); - This->resolving = isResolving; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + + TRACE("%p, %d.\n", iface, v); + + doc->resolving = v; return S_OK; } - -static HRESULT WINAPI domdoc_get_preserveWhiteSpace( - IXMLDOMDocument3 *iface, - VARIANT_BOOL* isPreserving ) +static HRESULT WINAPI domdoc_get_preserveWhiteSpace(IXMLDOMDocument3 *iface, VARIANT_BOOL *v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->properties->preserving); - *isPreserving = This->properties->preserving; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + struct domnode *node = doc->node; + + TRACE("%p, %p.\n", iface, v); + + *v = node->properties->preserving; return S_OK; } - -static HRESULT WINAPI domdoc_put_preserveWhiteSpace( - IXMLDOMDocument3 *iface, - VARIANT_BOOL isPreserving ) +static HRESULT WINAPI domdoc_put_preserveWhiteSpace(IXMLDOMDocument3 *iface, VARIANT_BOOL v) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%d)\n", This, isPreserving); - This->properties->preserving = isPreserving; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + struct domnode *node = doc->node; + + TRACE("%p, %d.\n", iface, v); + + node->properties->preserving = v; return S_OK; } - -static HRESULT WINAPI domdoc_put_onreadystatechange( - IXMLDOMDocument3 *iface, - VARIANT event ) +static HRESULT WINAPI domdoc_put_onreadystatechange(IXMLDOMDocument3 *iface, VARIANT event) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%s)\n", This, debugstr_variant(&event)); - return set_doc_event(This, EVENTID_READYSTATECHANGE, &event); -} + TRACE("%p, %s.\n", iface, debugstr_variant(&event)); + return set_doc_event(doc, EVENTID_READYSTATECHANGE, &event); +} static HRESULT WINAPI domdoc_put_onDataAvailable(IXMLDOMDocument3 *iface, VARIANT sink) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&sink)); + FIXME("%p, %s: stub\n", iface, debugstr_variant(&sink)); + return E_NOTIMPL; } -static HRESULT WINAPI domdoc_put_onTransformNode(IXMLDOMDocument3 *iface, VARIANT sink ) +static HRESULT WINAPI domdoc_put_onTransformNode(IXMLDOMDocument3 *iface, VARIANT sink) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&sink)); + FIXME("%p, %s: stub\n", iface, debugstr_variant(&sink)); + return E_NOTIMPL; } -static HRESULT WINAPI domdoc_get_namespaces( - IXMLDOMDocument3* iface, - IXMLDOMSchemaCollection** collection ) +static HRESULT WINAPI domdoc_get_namespaces(IXMLDOMDocument3 *iface, IXMLDOMSchemaCollection **collection) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + struct domnode *node = doc->node; HRESULT hr; - FIXME("(%p)->(%p): semi-stub\n", This, collection); + FIXME("%p, %p: semi-stub\n", iface, collection); - if (!collection) return E_POINTER; + if (!collection) + return E_POINTER; - if (!This->namespaces) + if (!doc->namespaces) { - hr = SchemaCache_create(This->properties->version, (void**)&This->namespaces); + hr = SchemaCache_create(node->properties->version, (void **)&doc->namespaces); if (hr != S_OK) return hr; - hr = cache_from_doc_ns(This->namespaces, &This->node); + hr = cache_from_doc_ns(doc->namespaces, doc->node); if (hr != S_OK) - release_namespaces(This); + release_namespaces(doc); } - if (This->namespaces) - return IXMLDOMSchemaCollection2_QueryInterface(This->namespaces, - &IID_IXMLDOMSchemaCollection, (void**)collection); + if (doc->namespaces) + return IXMLDOMSchemaCollection2_QueryInterface(doc->namespaces, &IID_IXMLDOMSchemaCollection, (void **)collection); return hr; } -static HRESULT WINAPI domdoc_get_schemas( - IXMLDOMDocument3* iface, - VARIANT* schema ) +static HRESULT WINAPI domdoc_get_schemas(IXMLDOMDocument3 *iface, VARIANT *schema) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - IXMLDOMSchemaCollection2* cur_schema = This->properties->schemaCache; + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + IXMLDOMSchemaCollection2 *cur_schema; + struct domnode *node = doc->node; HRESULT hr = S_FALSE; - TRACE("(%p)->(%p)\n", This, schema); + TRACE("%p, %p.\n", iface, schema); V_VT(schema) = VT_NULL; /* just to reset pointer part, cause that's what application is expected to use */ V_DISPATCH(schema) = NULL; - if(cur_schema) + if ((cur_schema = node->properties->schemaCache)) { hr = IXMLDOMSchemaCollection2_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(schema)); - if(SUCCEEDED(hr)) + if (SUCCEEDED(hr)) V_VT(schema) = VT_DISPATCH; } return hr; } -static HRESULT WINAPI domdoc_putref_schemas( - IXMLDOMDocument3* iface, - VARIANT schema) +static HRESULT WINAPI domdoc_putref_schemas(IXMLDOMDocument3 *iface, VARIANT schema) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + IXMLDOMSchemaCollection2 *new_schema = NULL; + struct domnode *node = doc->node; HRESULT hr = E_FAIL; - IXMLDOMSchemaCollection2* new_schema = NULL; - FIXME("(%p)->(%s): semi-stub\n", This, debugstr_variant(&schema)); + FIXME("%p, %s: semi-stub\n", iface, debugstr_variant(&schema)); + switch(V_VT(&schema)) { case VT_UNKNOWN: @@ -2883,153 +1783,47 @@ static HRESULT WINAPI domdoc_putref_schemas( WARN("Can't get schema from vt %x\n", V_VT(&schema)); } - if(SUCCEEDED(hr)) + if (SUCCEEDED(hr)) { - IXMLDOMSchemaCollection2* old_schema = InterlockedExchangePointer((void**)&This->properties->schemaCache, new_schema); - if(old_schema) IXMLDOMSchemaCollection2_Release(old_schema); + IXMLDOMSchemaCollection2 *old_schema = InterlockedExchangePointer((void **)&node->properties->schemaCache, new_schema); + if (old_schema) + IXMLDOMSchemaCollection2_Release(old_schema); } return hr; } -static inline BOOL is_wellformed(xmlDocPtr doc) -{ - return doc->properties & XML_DOC_WELLFORMED; -} - -static void LIBXML2_LOG_CALLBACK validate_error(void* ctx, char const* msg, ...) -{ - va_list ap; - va_start(ap, msg); - LIBXML2_CALLBACK_ERR(domdoc_validateNode, msg, ap); - va_end(ap); -} - -static void LIBXML2_LOG_CALLBACK validate_warning(void* ctx, char const* msg, ...) +static HRESULT WINAPI domdoc_validateNode(IXMLDOMDocument3 *iface, IXMLDOMNode *node, IXMLDOMParseError **err) { - va_list ap; - va_start(ap, msg); - LIBXML2_CALLBACK_WARN(domdoc_validateNode, msg, ap); - va_end(ap); -} + domdoc *doc = impl_from_IXMLDOMDocument3(iface); -static HRESULT WINAPI domdoc_validateNode( - IXMLDOMDocument3* iface, - IXMLDOMNode* node, - IXMLDOMParseError** err) -{ - domdoc* This = impl_from_IXMLDOMDocument3(iface); - LONG state, err_code = 0; - HRESULT hr = S_OK; - int validated = 0; + TRACE("%p, %p, %p.\n", iface, node, err); - TRACE("(%p)->(%p, %p)\n", This, node, err); - IXMLDOMDocument3_get_readyState(iface, &state); - if (state != READYSTATE_COMPLETE) - { - if (err) - *err = create_parseError(err_code, NULL, NULL, NULL, 0, 0, 0); - return E_PENDING; - } + /* TODO: check ready state */ if (!node) { if (err) - *err = create_parseError(err_code, NULL, NULL, NULL, 0, 0, 0); + *err = create_parseError(0, NULL, NULL, NULL, 0, 0, 0); return E_POINTER; } - if (!get_node_obj(node)->node || get_node_obj(node)->node->doc != get_doc(This)) - { - if (err) - *err = create_parseError(err_code, NULL, NULL, NULL, 0, 0, 0); - return E_FAIL; - } - - if (!is_wellformed(get_doc(This))) - { - ERR("doc not well-formed\n"); - if (err) - *err = create_parseError(E_XML_NOTWF, NULL, NULL, NULL, 0, 0, 0); - return S_FALSE; - } - - /* DTD validation */ - if (get_doc(This)->intSubset || get_doc(This)->extSubset) - { - xmlValidCtxtPtr vctx = xmlNewValidCtxt(); - vctx->error = validate_error; - vctx->warning = validate_warning; - ++validated; - - if (!((node == (IXMLDOMNode*)iface)? - xmlValidateDocument(vctx, get_doc(This)) : - xmlValidateElement(vctx, get_doc(This), get_node_obj(node)->node))) - { - /* TODO: get a real error code here */ - TRACE("DTD validation failed\n"); - err_code = E_XML_INVALID; - hr = S_FALSE; - } - xmlFreeValidCtxt(vctx); - } - - /* Schema validation */ - if (hr == S_OK && This->properties->schemaCache != NULL) - { - - hr = SchemaCache_validate_tree(This->properties->schemaCache, get_node_obj(node)->node); - if (SUCCEEDED(hr)) - { - ++validated; - /* TODO: get a real error code here */ - if (hr == S_OK) - { - TRACE("schema validation succeeded\n"); - } - else - { - ERR("schema validation failed\n"); - err_code = E_XML_INVALID; - } - } - else - { - /* not really OK, just didn't find a schema for the ns */ - hr = S_OK; - } - } - - if (!validated) - { - ERR("no DTD or schema found\n"); - err_code = E_XML_NODTD; - hr = S_FALSE; - } - - if (err) - *err = create_parseError(err_code, NULL, NULL, NULL, 0, 0, 0); - - return hr; + return node_validate(doc->node, node, err); } -static HRESULT WINAPI domdoc_validate( - IXMLDOMDocument3* iface, - IXMLDOMParseError** err) +static HRESULT WINAPI domdoc_validate(IXMLDOMDocument3 *iface, IXMLDOMParseError **err) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - TRACE("(%p)->(%p)\n", This, err); - return IXMLDOMDocument3_validateNode(iface, (IXMLDOMNode*)iface, err); + TRACE("%p, %p.\n", iface, err); + + return IXMLDOMDocument3_validateNode(iface, (IXMLDOMNode *)iface, err); } -static HRESULT WINAPI domdoc_setProperty( - IXMLDOMDocument3* iface, - BSTR p, - VARIANT value) +static HRESULT WINAPI domdoc_setProperty(IXMLDOMDocument3 *iface, BSTR p, VARIANT value) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); + struct domnode *node = doc->node; - TRACE("(%p)->(%s %s)\n", This, debugstr_w(p), debugstr_variant(&value)); + TRACE("%p, %s, %s.\n", iface, debugstr_w(p), debugstr_variant(&value)); if (wcsicmp(p, L"SelectionLanguage") == 0) { @@ -3049,18 +1843,18 @@ static HRESULT WINAPI domdoc_setProperty( hr = S_OK; if (wcsicmp(bstr, L"XPath") == 0) - This->properties->XPath = TRUE; + node->properties->XPath = TRUE; else if (wcsicmp(bstr, L"XSLPattern") == 0) - This->properties->XPath = FALSE; + node->properties->XPath = FALSE; else hr = E_FAIL; VariantClear(&varStr); return hr; } - else if (wcsicmp(p, L"SelectionNamespaces") == 0) + else if (!wcsicmp(p, L"SelectionNamespaces")) { - xmlChar *nsStr = (xmlChar*)This->properties->selectNsStr; + xmlChar *nsStr = (xmlChar *)node->properties->selectNsStr; struct list *pNsList; VARIANT varStr; HRESULT hr; @@ -3078,22 +1872,20 @@ static HRESULT WINAPI domdoc_setProperty( hr = S_OK; - pNsList = &(This->properties->selectNsList); - clear_selectNsList(pNsList); + pNsList = &node->properties->selectNsList; + domdoc_properties_clear_selection_namespaces(pNsList); free(nsStr); nsStr = xmlchar_from_wchar(bstr); TRACE("property value: \"%s\"\n", debugstr_w(bstr)); - This->properties->selectNsStr = nsStr; - This->properties->selectNsStr_len = xmlStrlen(nsStr); + node->properties->selectNsStr = nsStr; + node->properties->selectNsStr_len = xmlStrlen(nsStr); if (bstr && *bstr) { xmlChar *pTokBegin, *pTokEnd, *pTokInner; select_ns_entry* ns_entry = NULL; - xmlXPathContextPtr ctx; - ctx = xmlXPathNewContext(This->node.node->doc); pTokBegin = nsStr; /* skip leading spaces */ @@ -3158,11 +1950,7 @@ static HRESULT WINAPI domdoc_setProperty( ns_entry->href_end = *(pTokEnd-1); *(pTokEnd-1) = 0; list_add_tail(pNsList, &ns_entry->entry); - /*let libxml figure out if they're valid from here ;)*/ - if (xmlXPathRegisterNs(ctx, ns_entry->prefix, ns_entry->href) != 0) - { - hr = E_FAIL; - } + ns_entry = NULL; continue; } @@ -3184,7 +1972,6 @@ static HRESULT WINAPI domdoc_setProperty( } } free(ns_entry); - xmlXPathFreeContext(ctx); } VariantClear(&varStr); @@ -3192,11 +1979,11 @@ static HRESULT WINAPI domdoc_setProperty( } else if (wcsicmp(p, L"ValidateOnParse") == 0) { - if (This->properties->version < MSXML4) + if (node->properties->version < MSXML4) return E_FAIL; else { - This->properties->validating = V_BOOL(&value); + node->properties->validating = V_BOOL(&value); return S_OK; } } @@ -3218,27 +2005,24 @@ static HRESULT WINAPI domdoc_setProperty( return E_FAIL; } -static HRESULT WINAPI domdoc_getProperty( - IXMLDOMDocument3* iface, - BSTR p, - VARIANT* var) +static HRESULT WINAPI domdoc_getProperty(IXMLDOMDocument3 *iface, BSTR p, VARIANT *var) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); + domdoc *doc = impl_from_IXMLDOMDocument3(iface); - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), var); if (!var) return E_INVALIDARG; - if (wcsicmp(p, L"SelectionLanguage") == 0) + if (!wcsicmp(p, L"SelectionLanguage")) { V_VT(var) = VT_BSTR; - V_BSTR(var) = This->properties->XPath ? + V_BSTR(var) = doc->node->properties->XPath ? SysAllocString(L"XPath") : SysAllocString(L"XSLPattern"); return V_BSTR(var) ? S_OK : E_OUTOFMEMORY; } - else if (wcsicmp(p, L"SelectionNamespaces") == 0) + else if (!wcsicmp(p, L"SelectionNamespaces")) { int lenA, lenW; BSTR rebuiltStr, cur; @@ -3247,9 +2031,9 @@ static HRESULT WINAPI domdoc_getProperty( select_ns_entry* pNsEntry; V_VT(var) = VT_BSTR; - nsStr = This->properties->selectNsStr; - pNsList = &This->properties->selectNsList; - lenA = This->properties->selectNsStr_len; + nsStr = doc->node->properties->selectNsStr; + pNsList = &doc->node->properties->selectNsList; + lenA = doc->node->properties->selectNsStr_len; lenW = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)nsStr, lenA+1, NULL, 0); rebuiltStr = malloc(lenW * sizeof(WCHAR)); MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)nsStr, lenA+1, rebuiltStr, lenW); @@ -3273,14 +2057,14 @@ static HRESULT WINAPI domdoc_getProperty( free(rebuiltStr); return S_OK; } - else if (wcsicmp(p, L"ValidateOnParse") == 0) + else if (!wcsicmp(p, L"ValidateOnParse")) { - if (This->properties->version < MSXML4) + if (doc->node->properties->version < MSXML4) return E_FAIL; else { V_VT(var) = VT_BOOL; - V_BOOL(var) = This->properties->validating; + V_BOOL(var) = doc->node->properties->validating; return S_OK; } } @@ -3289,14 +2073,10 @@ static HRESULT WINAPI domdoc_getProperty( return E_FAIL; } -static HRESULT WINAPI domdoc_importNode( - IXMLDOMDocument3* iface, - IXMLDOMNode* node, - VARIANT_BOOL deep, - IXMLDOMNode** clone) +static HRESULT WINAPI domdoc_importNode(IXMLDOMDocument3 *iface, IXMLDOMNode *node, VARIANT_BOOL deep, IXMLDOMNode **clone) { - domdoc *This = impl_from_IXMLDOMDocument3( iface ); - FIXME("(%p)->(%p %d %p): stub\n", This, node, deep, clone); + FIXME("%p, %p, %d, %p: stub\n", iface, node, deep, clone); + return E_NOTIMPL; } @@ -3348,7 +2128,7 @@ static const struct IXMLDOMDocument3Vtbl XMLDOMDocument3Vtbl = domdoc_get_doctype, domdoc_get_implementation, domdoc_get_documentElement, - domdoc_put_documentElement, + domdoc_putref_documentElement, domdoc_createElement, domdoc_createDocumentFragment, domdoc_createTextNode, @@ -3392,41 +2172,41 @@ static const struct IXMLDOMDocument3Vtbl XMLDOMDocument3Vtbl = static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface, REFIID riid, void **ppv) { - domdoc *This = impl_from_IConnectionPointContainer(iface); - return IXMLDOMDocument3_QueryInterface(&This->IXMLDOMDocument3_iface, riid, ppv); + domdoc *doc = impl_from_IConnectionPointContainer(iface); + return IXMLDOMDocument3_QueryInterface(&doc->IXMLDOMDocument3_iface, riid, ppv); } static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface) { - domdoc *This = impl_from_IConnectionPointContainer(iface); - return IXMLDOMDocument3_AddRef(&This->IXMLDOMDocument3_iface); + domdoc *doc = impl_from_IConnectionPointContainer(iface); + return IXMLDOMDocument3_AddRef(&doc->IXMLDOMDocument3_iface); } static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface) { - domdoc *This = impl_from_IConnectionPointContainer(iface); - return IXMLDOMDocument3_Release(&This->IXMLDOMDocument3_iface); + domdoc *doc = impl_from_IConnectionPointContainer(iface); + return IXMLDOMDocument3_Release(&doc->IXMLDOMDocument3_iface); } static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface, IEnumConnectionPoints **ppEnum) { - domdoc *This = impl_from_IConnectionPointContainer(iface); - FIXME("(%p)->(%p): stub\n", This, ppEnum); + FIXME("%p, %p: stub\n", iface, ppEnum); + return E_NOTIMPL; } static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface, REFIID riid, IConnectionPoint **cp) { - domdoc *This = impl_from_IConnectionPointContainer(iface); + domdoc *doc = impl_from_IConnectionPointContainer(iface); ConnectionPoint *iter; - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), cp); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), cp); *cp = NULL; - for(iter = This->cp_list; iter; iter = iter->next) + for (iter = doc->cp_list; iter; iter = iter->next) { if (IsEqualGUID(iter->iid, riid)) *cp = &iter->IConnectionPoint_iface; @@ -3440,7 +2220,6 @@ static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPo FIXME("unsupported riid %s\n", debugstr_guid(riid)); return CONNECT_E_NOCONNECTION; - } static const struct IConnectionPointContainerVtbl ConnectionPointContainerVtbl = @@ -3452,13 +2231,9 @@ static const struct IConnectionPointContainerVtbl ConnectionPointContainerVtbl = ConnectionPointContainer_FindConnectionPoint }; -/* IConnectionPoint */ -static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface, - REFIID riid, void **ppv) +static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface, REFIID riid, void **ppv) { - ConnectionPoint *This = impl_from_IConnectionPoint(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv ); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), ppv); *ppv = NULL; @@ -3604,68 +2379,66 @@ static void ConnectionPoint_Init(ConnectionPoint *cp, struct domdoc *doc, REFIID cp->container = &doc->IConnectionPointContainer_iface; } -/* domdoc implementation of IObjectWithSite */ -static HRESULT WINAPI -domdoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject ) +static HRESULT WINAPI domdoc_ObjectWithSite_QueryInterface(IObjectWithSite* iface, REFIID riid, void **obj) { - domdoc *This = impl_from_IObjectWithSite(iface); - return IXMLDOMDocument3_QueryInterface(&This->IXMLDOMDocument3_iface, riid, ppvObject); + domdoc *doc = impl_from_IObjectWithSite(iface); + return IXMLDOMDocument3_QueryInterface(&doc->IXMLDOMDocument3_iface, riid, obj); } -static ULONG WINAPI domdoc_ObjectWithSite_AddRef( IObjectWithSite* iface ) +static ULONG WINAPI domdoc_ObjectWithSite_AddRef(IObjectWithSite *iface) { - domdoc *This = impl_from_IObjectWithSite(iface); - return IXMLDOMDocument3_AddRef(&This->IXMLDOMDocument3_iface); + domdoc *doc = impl_from_IObjectWithSite(iface); + return IXMLDOMDocument3_AddRef(&doc->IXMLDOMDocument3_iface); } -static ULONG WINAPI domdoc_ObjectWithSite_Release( IObjectWithSite* iface ) +static ULONG WINAPI domdoc_ObjectWithSite_Release(IObjectWithSite *iface) { - domdoc *This = impl_from_IObjectWithSite(iface); - return IXMLDOMDocument3_Release(&This->IXMLDOMDocument3_iface); + domdoc *doc = impl_from_IObjectWithSite(iface); + return IXMLDOMDocument3_Release(&doc->IXMLDOMDocument3_iface); } -static HRESULT WINAPI domdoc_ObjectWithSite_GetSite( IObjectWithSite *iface, REFIID iid, void **ppvSite ) +static HRESULT WINAPI domdoc_ObjectWithSite_GetSite(IObjectWithSite *iface, REFIID iid, void **obj) { - domdoc *This = impl_from_IObjectWithSite(iface); + domdoc *doc = impl_from_IObjectWithSite(iface); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite ); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(iid), obj); - if ( !This->site ) + if (!doc->site) return E_FAIL; - return IUnknown_QueryInterface( This->site, iid, ppvSite ); + return IUnknown_QueryInterface(doc->site, iid, obj); } -static HRESULT WINAPI domdoc_ObjectWithSite_SetSite( IObjectWithSite *iface, IUnknown *punk ) +static HRESULT WINAPI domdoc_ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *punk) { - domdoc *This = impl_from_IObjectWithSite(iface); + domdoc *doc = impl_from_IObjectWithSite(iface); - TRACE("(%p)->(%p)\n", iface, punk); + TRACE("%p, %p.\n", iface, punk); - if(!punk) + if (!punk) { - if(This->site) + if (doc->site) { - IUnknown_Release( This->site ); - This->site = NULL; + IUnknown_Release(doc->site); + doc->site = NULL; } - if(This->base_uri) + if (doc->base_uri) { - IUri_Release(This->base_uri); - This->base_uri = NULL; + IUri_Release(doc->base_uri); + doc->base_uri = NULL; } return S_OK; } - IUnknown_AddRef( punk ); + IUnknown_AddRef(punk); - if(This->site) - IUnknown_Release( This->site ); + if (doc->site) + IUnknown_Release(doc->site); - This->site = punk; - This->base_uri = get_base_uri(This->site); + doc->site = punk; + doc->base_uri = get_base_uri(doc->site); return S_OK; } @@ -3681,20 +2454,20 @@ static const IObjectWithSiteVtbl domdocObjectSite = static HRESULT WINAPI domdoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv) { - domdoc *This = impl_from_IObjectSafety(iface); - return IXMLDOMDocument3_QueryInterface(&This->IXMLDOMDocument3_iface, riid, ppv); + domdoc *doc = impl_from_IObjectSafety(iface); + return IXMLDOMDocument3_QueryInterface(&doc->IXMLDOMDocument3_iface, riid, ppv); } static ULONG WINAPI domdoc_Safety_AddRef(IObjectSafety *iface) { - domdoc *This = impl_from_IObjectSafety(iface); - return IXMLDOMDocument3_AddRef(&This->IXMLDOMDocument3_iface); + domdoc *doc = impl_from_IObjectSafety(iface); + return IXMLDOMDocument3_AddRef(&doc->IXMLDOMDocument3_iface); } static ULONG WINAPI domdoc_Safety_Release(IObjectSafety *iface) { - domdoc *This = impl_from_IObjectSafety(iface); - return IXMLDOMDocument3_Release(&This->IXMLDOMDocument3_iface); + domdoc *doc = impl_from_IObjectSafety(iface); + return IXMLDOMDocument3_Release(&doc->IXMLDOMDocument3_iface); } #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER) @@ -3702,14 +2475,15 @@ static ULONG WINAPI domdoc_Safety_Release(IObjectSafety *iface) static HRESULT WINAPI domdoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid, DWORD *supported, DWORD *enabled) { - domdoc *This = impl_from_IObjectSafety(iface); + domdoc *doc = impl_from_IObjectSafety(iface); - TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), supported, enabled); + TRACE("%p, %s, %p, %p.\n", iface, debugstr_guid(riid), supported, enabled); - if(!supported || !enabled) return E_POINTER; + if (!supported || !enabled) + return E_POINTER; *supported = SAFETY_SUPPORTED_OPTIONS; - *enabled = This->safeopt; + *enabled = doc->safeopt; return S_OK; } @@ -3739,7 +2513,8 @@ static const IObjectSafetyVtbl domdocObjectSafetyVtbl = { domdoc_Safety_SetInterfaceSafetyOptions }; -static const tid_t domdoc_iface_tids[] = { +static const tid_t domdoc_iface_tids[] = +{ IXMLDOMDocument3_tid, 0 }; @@ -3751,85 +2526,51 @@ static dispex_static_data_t domdoc_dispex = { domdoc_iface_tids }; -HRESULT get_domdoc_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document) -{ - domdoc *doc; - - doc = malloc(sizeof(*doc)); - if( !doc ) - return E_OUTOFMEMORY; - - doc->IXMLDOMDocument3_iface.lpVtbl = &XMLDOMDocument3Vtbl; - doc->IPersistStreamInit_iface.lpVtbl = &xmldoc_IPersistStreamInit_VTable; - doc->IObjectWithSite_iface.lpVtbl = &domdocObjectSite; - doc->IObjectSafety_iface.lpVtbl = &domdocObjectSafetyVtbl; - doc->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl; - doc->ref = 1; - doc->async = VARIANT_TRUE; - doc->resolving = 0; - doc->properties = properties_add_ref(properties_from_xmlDocPtr(xmldoc)); - doc->error = S_OK; - doc->site = NULL; - doc->base_uri = NULL; - doc->safeopt = 0; - doc->cp_list = NULL; - doc->namespaces = NULL; - memset(doc->events, 0, sizeof(doc->events)); - - /* events connection points */ - ConnectionPoint_Init(&doc->cp_dispatch, doc, &IID_IDispatch); - ConnectionPoint_Init(&doc->cp_propnotif, doc, &IID_IPropertyNotifySink); - ConnectionPoint_Init(&doc->cp_domdocevents, doc, &DIID_XMLDOMDocumentEvents); - - init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IXMLDOMNode*)&doc->IXMLDOMDocument3_iface, - &domdoc_dispex); - - *document = &doc->IXMLDOMDocument3_iface; - - TRACE("returning iface %p\n", *document); - return S_OK; -} - -HRESULT dom_document_create(MSXML_VERSION version, void **ppObj) +HRESULT dom_document_create(MSXML_VERSION version, void **obj) { - xmlDocPtr xmldoc; + struct domnode *node; HRESULT hr; - TRACE("(%d, %p)\n", version, ppObj); - - xmldoc = xmlNewDoc(NULL); - if(!xmldoc) - return E_OUTOFMEMORY; + TRACE("%d, %p.\n", version, obj); - xmldoc_init(xmldoc, version); + *obj = NULL; - hr = get_domdoc_from_xmldoc(xmldoc, (IXMLDOMDocument3**)ppObj); - if(FAILED(hr)) - { - properties_release(properties_from_xmlDocPtr(xmldoc)); - free(xmldoc->_private); - xmlFreeDoc(xmldoc); + if (FAILED(hr = domnode_create(NODE_DOCUMENT, NULL, 0, NULL, 0, NULL, &node))) return hr; - } + node->properties = domdoc_create_properties(version); + + hr = create_domdoc(node, (IUnknown **)obj); + if (FAILED(hr)) + domnode_destroy_tree(node); return hr; } -IUnknown* create_domdoc( xmlNodePtr node ) +HRESULT create_domdoc(struct domnode *node, IUnknown **obj) { - xmlDocPtr doc = (xmlDocPtr)node; - IUnknown *obj = NULL; - HRESULT hr; + domdoc *object; - TRACE("(%p)\n", node); + *obj = NULL; - if (!doc->_private) - xmldoc_init(doc, MSXML6); - xmldoc_add_ref(doc); + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; - hr = get_domdoc_from_xmldoc(doc, (IXMLDOMDocument3**)&obj); - if (FAILED(hr)) - return NULL; + object->IXMLDOMDocument3_iface.lpVtbl = &XMLDOMDocument3Vtbl; + object->IPersistStreamInit_iface.lpVtbl = &xmldoc_IPersistStreamInit_VTable; + object->IObjectWithSite_iface.lpVtbl = &domdocObjectSite; + object->IObjectSafety_iface.lpVtbl = &domdocObjectSafetyVtbl; + object->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl; + object->refcount = 1; + object->async = VARIANT_TRUE; + object->node = domnode_addref(node); - return obj; + ConnectionPoint_Init(&object->cp_dispatch, object, &IID_IDispatch); + ConnectionPoint_Init(&object->cp_propnotif, object, &IID_IPropertyNotifySink); + ConnectionPoint_Init(&object->cp_domdocevents, object, &DIID_XMLDOMDocumentEvents); + + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMDocument3_iface, &domdoc_dispex); + + *obj = (IUnknown *)&object->IXMLDOMDocument3_iface; + + return S_OK; } diff --git a/dlls/msxml3/domimpl.c b/dlls/msxml3/domimpl.c index 6442df3dcd3..4735c357b91 100644 --- a/dlls/msxml3/domimpl.c +++ b/dlls/msxml3/domimpl.c @@ -38,7 +38,7 @@ typedef struct _domimpl { DispatchEx dispex; IXMLDOMImplementation IXMLDOMImplementation_iface; - LONG ref; + LONG refcount; } domimpl; static inline domimpl *impl_from_IXMLDOMImplementation( IXMLDOMImplementation *iface ) @@ -46,32 +46,30 @@ static inline domimpl *impl_from_IXMLDOMImplementation( IXMLDOMImplementation *i return CONTAINING_RECORD(iface, domimpl, IXMLDOMImplementation_iface); } -static HRESULT WINAPI domimpl_QueryInterface( - IXMLDOMImplementation *iface, - REFIID riid, - void** ppvObject ) +static HRESULT WINAPI domimpl_QueryInterface(IXMLDOMImplementation *iface, REFIID riid, void **obj) { - domimpl *This = impl_from_IXMLDOMImplementation( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + domimpl *domimpl = impl_from_IXMLDOMImplementation(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); - if ( IsEqualGUID( riid, &IID_IXMLDOMImplementation ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IUnknown ) ) + if (IsEqualGUID(riid, &IID_IXMLDOMImplementation) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IUnknown)) { - *ppvObject = iface; + *obj = iface; } - else if (dispex_query_interface(&This->dispex, riid, ppvObject)) + else if (dispex_query_interface(&domimpl->dispex, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } else { TRACE("Unsupported interface %s\n", debugstr_guid(riid)); - *ppvObject = NULL; + *obj = NULL; return E_NOINTERFACE; } - IXMLDOMImplementation_AddRef( iface ); + IXMLDOMImplementation_AddRef(iface); return S_OK; } @@ -79,69 +77,60 @@ static HRESULT WINAPI domimpl_QueryInterface( static ULONG WINAPI domimpl_AddRef(IXMLDOMImplementation *iface) { domimpl *domimpl = impl_from_IXMLDOMImplementation(iface); - ULONG ref = InterlockedIncrement(&domimpl->ref); - TRACE("%p, refcount %lu.\n", iface, ref); - return ref; + ULONG refcount = InterlockedIncrement(&domimpl->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); + + return refcount; } static ULONG WINAPI domimpl_Release(IXMLDOMImplementation *iface) { domimpl *domimpl = impl_from_IXMLDOMImplementation(iface); - ULONG ref = InterlockedDecrement(&domimpl->ref); + ULONG refcount = InterlockedDecrement(&domimpl->refcount); - TRACE("%p, refcount %lu.\n", iface, ref); + TRACE("%p, refcount %lu.\n", iface, refcount); - if (!ref) + if (!refcount) free(domimpl); - return ref; + return refcount; } -static HRESULT WINAPI domimpl_GetTypeInfoCount( - IXMLDOMImplementation *iface, - UINT* pctinfo ) +static HRESULT WINAPI domimpl_GetTypeInfoCount(IXMLDOMImplementation *iface, UINT *count) { - domimpl *This = impl_from_IXMLDOMImplementation( iface ); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); + domimpl *domimpl = impl_from_IXMLDOMImplementation(iface); + return IDispatchEx_GetTypeInfoCount(&domimpl->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI domimpl_GetTypeInfo( - IXMLDOMImplementation *iface, - UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI domimpl_GetTypeInfo(IXMLDOMImplementation *iface, UINT index, LCID lcid, ITypeInfo **ti) { - domimpl *This = impl_from_IXMLDOMImplementation( iface ); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + domimpl *domimpl = impl_from_IXMLDOMImplementation(iface); + return IDispatchEx_GetTypeInfo(&domimpl->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI domimpl_GetIDsOfNames( - IXMLDOMImplementation *iface, - REFIID riid, LPOLESTR* rgszNames, - UINT cNames, LCID lcid, DISPID* rgDispId ) +static HRESULT WINAPI domimpl_GetIDsOfNames(IXMLDOMImplementation *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { - domimpl *This = impl_from_IXMLDOMImplementation( iface ); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, - riid, rgszNames, cNames, lcid, rgDispId); + domimpl *domimpl = impl_from_IXMLDOMImplementation(iface); + return IDispatchEx_GetIDsOfNames(&domimpl->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); } -static HRESULT WINAPI domimpl_Invoke( - IXMLDOMImplementation *iface, - DISPID dispIdMember, REFIID riid, LCID lcid, - WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr ) +static HRESULT WINAPI domimpl_Invoke(IXMLDOMImplementation *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, + EXCEPINFO *ei, UINT *puArgErr) { - domimpl *This = impl_from_IXMLDOMImplementation( iface ); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + domimpl *domimpl = impl_from_IXMLDOMImplementation(iface); + return IDispatchEx_Invoke(&domimpl->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, flags, + params, result, ei, puArgErr); } -static HRESULT WINAPI domimpl_hasFeature(IXMLDOMImplementation* This, BSTR feature, BSTR version, VARIANT_BOOL *hasFeature) +static HRESULT WINAPI domimpl_hasFeature(IXMLDOMImplementation *iface, BSTR feature, BSTR version, VARIANT_BOOL *hasFeature) { BOOL bValidFeature = FALSE; BOOL bValidVersion = FALSE; - TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(feature), debugstr_w(version), hasFeature); + TRACE("%p, %s, %s, %p.\n", iface, debugstr_w(feature), debugstr_w(version), hasFeature); if(!feature || !hasFeature) return E_INVALIDARG; @@ -194,7 +183,7 @@ HRESULT create_dom_implementation(IXMLDOMImplementation **ret) return E_OUTOFMEMORY; object->IXMLDOMImplementation_iface.lpVtbl = &domimpl_vtbl; - object->ref = 1; + object->refcount = 1; init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMImplementation_iface, &domimpl_dispex); *ret = &object->IXMLDOMImplementation_iface; diff --git a/dlls/msxml3/element.c b/dlls/msxml3/element.c index fd9a2973cd8..35a41b09157 100644 --- a/dlls/msxml3/element.c +++ b/dlls/msxml3/element.c @@ -21,8 +21,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> #include "windef.h" #include "winbase.h" @@ -37,393 +35,316 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); -static const xmlChar DT_prefix[] = "dt"; -static const xmlChar DT_nsURI[] = "urn:schemas-microsoft-com:datatypes"; - typedef struct _domelem { - xmlnode node; + DispatchEx dispex; IXMLDOMElement IXMLDOMElement_iface; - LONG ref; + LONG refcount; + struct domnode *node; } domelem; static const struct nodemap_funcs domelem_attr_map; -static const tid_t domelem_se_tids[] = { +static const tid_t domelem_se_tids[] = +{ IXMLDOMNode_tid, IXMLDOMElement_tid, NULL_tid }; -static inline domelem *impl_from_IXMLDOMElement( IXMLDOMElement *iface ) +static inline domelem *impl_from_IXMLDOMElement(IXMLDOMElement *iface) { return CONTAINING_RECORD(iface, domelem, IXMLDOMElement_iface); } -static inline xmlNodePtr get_element( const domelem *This ) +static HRESULT WINAPI domelem_QueryInterface(IXMLDOMElement *iface, REFIID riid, void **obj) { - return This->node.node; -} - -static HRESULT WINAPI domelem_QueryInterface( - IXMLDOMElement *iface, - REFIID riid, - void** ppvObject ) -{ - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); - if ( IsEqualGUID( riid, &IID_IXMLDOMElement ) || - IsEqualGUID( riid, &IID_IXMLDOMNode ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IUnknown ) ) + if (IsEqualGUID(riid, &IID_IXMLDOMElement) || + IsEqualGUID(riid, &IID_IXMLDOMNode) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IUnknown)) { - *ppvObject = &This->IXMLDOMElement_iface; + *obj = &element->IXMLDOMElement_iface; } - else if(node_query_interface(&This->node, riid, ppvObject)) + else if (dispex_query_interface(&element->dispex, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } - else if(IsEqualGUID( riid, &IID_ISupportErrorInfo )) + else if (node_query_interface(element->node, riid, obj)) { - return node_create_supporterrorinfo(domelem_se_tids, ppvObject); + return *obj ? S_OK : E_NOINTERFACE; + } + else if (IsEqualGUID(riid, &IID_ISupportErrorInfo)) + { + return node_create_supporterrorinfo(domelem_se_tids, obj); } else { TRACE("interface %s not implemented\n", debugstr_guid(riid)); - *ppvObject = NULL; + *obj = NULL; return E_NOINTERFACE; } - IUnknown_AddRef( (IUnknown*)*ppvObject ); + IUnknown_AddRef((IUnknown *)*obj); return S_OK; } static ULONG WINAPI domelem_AddRef(IXMLDOMElement *iface) { domelem *element = impl_from_IXMLDOMElement(iface); - LONG ref = InterlockedIncrement(&element->ref); + LONG refcount = InterlockedIncrement(&element->refcount); - TRACE("%p, refcount %ld.\n", iface, ref); + TRACE("%p, refcount %ld.\n", iface, refcount); - return ref; + return refcount; } static ULONG WINAPI domelem_Release(IXMLDOMElement *iface) { domelem *element = impl_from_IXMLDOMElement(iface); - ULONG ref = InterlockedDecrement(&element->ref); + ULONG refcount = InterlockedDecrement(&element->refcount); - TRACE("%p, refcount %lu.\n", iface, ref); + TRACE("%p, refcount %lu.\n", iface, refcount); - if (!ref) + if (!refcount) { - destroy_xmlnode(&element->node); + domnode_release(element->node); free(element); } - return ref; + return refcount; } -static HRESULT WINAPI domelem_GetTypeInfoCount( - IXMLDOMElement *iface, - UINT* pctinfo ) +static HRESULT WINAPI domelem_GetTypeInfoCount(IXMLDOMElement *iface, UINT *count) { - domelem *This = impl_from_IXMLDOMElement( iface ); - return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); + domelem *element = impl_from_IXMLDOMElement(iface); + return IDispatchEx_GetTypeInfoCount(&element->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI domelem_GetTypeInfo( - IXMLDOMElement *iface, - UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI domelem_GetTypeInfo(IXMLDOMElement *iface, UINT index, LCID lcid, ITypeInfo **ti) { - domelem *This = impl_from_IXMLDOMElement( iface ); - return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + domelem *element = impl_from_IXMLDOMElement(iface); + return IDispatchEx_GetTypeInfo(&element->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI domelem_GetIDsOfNames( - IXMLDOMElement *iface, - REFIID riid, LPOLESTR* rgszNames, - UINT cNames, LCID lcid, DISPID* rgDispId ) +static HRESULT WINAPI domelem_GetIDsOfNames(IXMLDOMElement *iface, REFIID riid, LPOLESTR* rgszNames, + UINT cNames, LCID lcid, DISPID* rgDispId) { - domelem *This = impl_from_IXMLDOMElement( iface ); - return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, - riid, rgszNames, cNames, lcid, rgDispId); + domelem *element = impl_from_IXMLDOMElement(iface); + return IDispatchEx_GetIDsOfNames(&element->dispex.IDispatchEx_iface, riid, rgszNames, + cNames, lcid, rgDispId); } -static HRESULT WINAPI domelem_Invoke( - IXMLDOMElement *iface, - DISPID dispIdMember, REFIID riid, LCID lcid, - WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr ) +static HRESULT WINAPI domelem_Invoke(IXMLDOMElement *iface, DISPID dispIdMember, REFIID riid, LCID lcid, + WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { - domelem *This = impl_from_IXMLDOMElement( iface ); - return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + domelem *element = impl_from_IXMLDOMElement(iface); + return IDispatchEx_Invoke(&element->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); } -static HRESULT WINAPI domelem_get_nodeName( - IXMLDOMElement *iface, - BSTR* p ) +static HRESULT WINAPI domelem_get_nodeName(IXMLDOMElement *iface, BSTR *p) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_nodeName(&This->node, p); + return node_get_name(element->node, p); } -static HRESULT WINAPI domelem_get_nodeValue( - IXMLDOMElement *iface, - VARIANT* value) +static HRESULT WINAPI domelem_get_nodeValue(IXMLDOMElement *iface, VARIANT *value) { - domelem *This = impl_from_IXMLDOMElement( iface ); + TRACE("%p, %p.\n", iface, value); - TRACE("(%p)->(%p)\n", This, value); - - if(!value) - return E_INVALIDARG; - - V_VT(value) = VT_NULL; - V_BSTR(value) = NULL; /* tests show that we should do this */ - return S_FALSE; + return return_null_var(value); } -static HRESULT WINAPI domelem_put_nodeValue( - IXMLDOMElement *iface, - VARIANT value) +static HRESULT WINAPI domelem_put_nodeValue(IXMLDOMElement *iface, VARIANT value) { - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + TRACE("%p, %s.\n", iface, debugstr_variant(&value)); + return E_FAIL; } -static HRESULT WINAPI domelem_get_nodeType( - IXMLDOMElement *iface, - DOMNodeType* domNodeType ) +static HRESULT WINAPI domelem_get_nodeType(IXMLDOMElement *iface, DOMNodeType *type) { - domelem *This = impl_from_IXMLDOMElement( iface ); - - TRACE("(%p)->(%p)\n", This, domNodeType); + TRACE("%p, %p.\n", iface, type); - *domNodeType = NODE_ELEMENT; + *type = NODE_ELEMENT; return S_OK; } -static HRESULT WINAPI domelem_get_parentNode( - IXMLDOMElement *iface, - IXMLDOMNode** parent ) +static HRESULT WINAPI domelem_get_parentNode(IXMLDOMElement *iface, IXMLDOMNode **parent) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); - TRACE("(%p)->(%p)\n", This, parent); + TRACE("%p, %p.\n", iface, parent); - return node_get_parent(&This->node, parent); + return node_get_parent(element->node, parent); } -static HRESULT WINAPI domelem_get_childNodes( - IXMLDOMElement *iface, - IXMLDOMNodeList** outList) +static HRESULT WINAPI domelem_get_childNodes(IXMLDOMElement *iface, IXMLDOMNodeList **list) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); - TRACE("(%p)->(%p)\n", This, outList); + TRACE("%p, %p.\n", iface, list); - return node_get_child_nodes(&This->node, outList); + return node_get_child_nodes(element->node, list); } -static HRESULT WINAPI domelem_get_firstChild( - IXMLDOMElement *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domelem_get_firstChild(IXMLDOMElement *iface, IXMLDOMNode **node) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_first_child(&This->node, domNode); + return node_get_first_child(element->node, node); } -static HRESULT WINAPI domelem_get_lastChild( - IXMLDOMElement *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domelem_get_lastChild(IXMLDOMElement *iface, IXMLDOMNode **node) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_last_child(&This->node, domNode); + return node_get_last_child(element->node, node); } -static HRESULT WINAPI domelem_get_previousSibling( - IXMLDOMElement *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domelem_get_previousSibling(IXMLDOMElement *iface, IXMLDOMNode **node) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_previous_sibling(&This->node, domNode); + return node_get_previous_sibling(element->node, node); } -static HRESULT WINAPI domelem_get_nextSibling( - IXMLDOMElement *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domelem_get_nextSibling(IXMLDOMElement *iface, IXMLDOMNode **node) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_next_sibling(&This->node, domNode); + return node_get_next_sibling(element->node, node); } -static HRESULT WINAPI domelem_get_attributes( - IXMLDOMElement *iface, - IXMLDOMNamedNodeMap** map) +static HRESULT WINAPI domelem_get_attributes(IXMLDOMElement *iface, IXMLDOMNamedNodeMap **map) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); - TRACE("(%p)->(%p)\n", This, map); + TRACE("%p, %p.\n", iface, map); - *map = create_nodemap(This->node.node, &domelem_attr_map); - return S_OK; + return create_nodemap(element->node, &domelem_attr_map, map); } -static HRESULT WINAPI domelem_insertBefore( - IXMLDOMElement *iface, - IXMLDOMNode* newNode, VARIANT refChild, - IXMLDOMNode** old_node) +static HRESULT WINAPI domelem_insertBefore(IXMLDOMElement *iface, + IXMLDOMNode *newNode, VARIANT refChild, IXMLDOMNode **old_node) { - domelem *This = impl_from_IXMLDOMElement( iface ); - DOMNodeType type; - HRESULT hr; - - TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), old_node); - - if (!newNode) return E_INVALIDARG; + domelem *element = impl_from_IXMLDOMElement(iface); - hr = IXMLDOMNode_get_nodeType(newNode, &type); - if (hr != S_OK) return hr; + TRACE("%p, %p, %s, %p.\n", iface, newNode, debugstr_variant(&refChild), old_node); - TRACE("new node type %d\n", type); - switch (type) - { - case NODE_DOCUMENT: - case NODE_DOCUMENT_TYPE: - case NODE_ENTITY: - case NODE_NOTATION: - if (old_node) *old_node = NULL; - return E_FAIL; - default: - return node_insert_before(&This->node, newNode, &refChild, old_node); - } + return node_insert_before(element->node, newNode, &refChild, old_node); } -static HRESULT WINAPI domelem_replaceChild( - IXMLDOMElement *iface, - IXMLDOMNode* newNode, - IXMLDOMNode* oldNode, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI domelem_replaceChild(IXMLDOMElement *iface, + IXMLDOMNode *newNode, IXMLDOMNode *oldNode, IXMLDOMNode **outOldNode) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); - TRACE("(%p)->(%p %p %p)\n", This, newNode, oldNode, outOldNode); + TRACE("%p, %p, %p, %p.\n", iface, newNode, oldNode, outOldNode); - return node_replace_child(&This->node, newNode, oldNode, outOldNode); + return node_replace_child(element->node, newNode, oldNode, outOldNode); } -static HRESULT WINAPI domelem_removeChild( - IXMLDOMElement *iface, - IXMLDOMNode *child, IXMLDOMNode **oldChild) +static HRESULT WINAPI domelem_removeChild(IXMLDOMElement *iface, + IXMLDOMNode *child, IXMLDOMNode **oldChild) { - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%p %p)\n", This, child, oldChild); - return node_remove_child(&This->node, child, oldChild); + domelem *element = impl_from_IXMLDOMElement(iface); + + TRACE("%p, %p, %p.\n", iface, child, oldChild); + + return node_remove_child(element->node, child, oldChild); } -static HRESULT WINAPI domelem_appendChild( - IXMLDOMElement *iface, - IXMLDOMNode *child, IXMLDOMNode **outChild) +static HRESULT WINAPI domelem_appendChild(IXMLDOMElement *iface, + IXMLDOMNode *child, IXMLDOMNode **outChild) { - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%p %p)\n", This, child, outChild); - return node_append_child(&This->node, child, outChild); + domelem *element = impl_from_IXMLDOMElement(iface); + + TRACE("%p, %p, %p.\n", iface, child, outChild); + + return node_append_child(element->node, child, outChild); } -static HRESULT WINAPI domelem_hasChildNodes( - IXMLDOMElement *iface, - VARIANT_BOOL *ret) +static HRESULT WINAPI domelem_hasChildNodes(IXMLDOMElement *iface, VARIANT_BOOL *ret) { - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%p)\n", This, ret); - return node_has_childnodes(&This->node, ret); + domelem *element = impl_from_IXMLDOMElement(iface); + + TRACE("%p, %p.\n", iface, ret); + + return node_has_childnodes(element->node, ret); } -static HRESULT WINAPI domelem_get_ownerDocument( - IXMLDOMElement *iface, - IXMLDOMDocument **doc) +static HRESULT WINAPI domelem_get_ownerDocument(IXMLDOMElement *iface, IXMLDOMDocument **doc) { - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%p)\n", This, doc); - return node_get_owner_doc(&This->node, doc); + domelem *element = impl_from_IXMLDOMElement(iface); + + TRACE("%p, %p.\n", iface, doc); + + return node_get_owner_document(element->node, doc); } -static HRESULT WINAPI domelem_cloneNode( - IXMLDOMElement *iface, - VARIANT_BOOL deep, IXMLDOMNode** outNode) +static HRESULT WINAPI domelem_cloneNode(IXMLDOMElement *iface, VARIANT_BOOL deep, IXMLDOMNode **node) { - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%d %p)\n", This, deep, outNode); - return node_clone( &This->node, deep, outNode ); + domelem *element = impl_from_IXMLDOMElement(iface); + + TRACE("%p, %d, %p.\n", iface, deep, node); + + return node_clone(element->node, deep, node); } -static HRESULT WINAPI domelem_get_nodeTypeString( - IXMLDOMElement *iface, - BSTR* p) +static HRESULT WINAPI domelem_get_nodeTypeString(IXMLDOMElement *iface, BSTR *p) { - domelem *This = impl_from_IXMLDOMElement( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"element", p); } -static HRESULT WINAPI domelem_get_text( - IXMLDOMElement *iface, - BSTR* p) +static HRESULT WINAPI domelem_get_text(IXMLDOMElement *iface, BSTR *p) { - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_text(&This->node, p); + domelem *element = impl_from_IXMLDOMElement(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_text(element->node, p); } -static HRESULT WINAPI domelem_put_text( - IXMLDOMElement *iface, - BSTR p) +static HRESULT WINAPI domelem_put_text(IXMLDOMElement *iface, BSTR p) { - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - return node_put_text( &This->node, p ); + domelem *element = impl_from_IXMLDOMElement(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(p)); + + return node_put_data(element->node, p); } -static HRESULT WINAPI domelem_get_specified( - IXMLDOMElement *iface, - VARIANT_BOOL* isSpecified) +static HRESULT WINAPI domelem_get_specified(IXMLDOMElement *iface, VARIANT_BOOL *v) { - domelem *This = impl_from_IXMLDOMElement( iface ); - FIXME("(%p)->(%p) stub!\n", This, isSpecified); - *isSpecified = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domelem_get_definition( - IXMLDOMElement *iface, - IXMLDOMNode** definitionNode) +static HRESULT WINAPI domelem_get_definition(IXMLDOMElement *iface, IXMLDOMNode **node) { - domelem *This = impl_from_IXMLDOMElement( iface ); - FIXME("(%p)->(%p)\n", This, definitionNode); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } @@ -443,11 +364,10 @@ static inline BYTE base64_to_byte(xmlChar c) return c-'a'+26; } -static inline HRESULT variant_from_dt(XDR_DT dt, xmlChar* str, VARIANT* v) +static inline HRESULT variant_from_dt(XDR_DT dt, WCHAR *str, VARIANT *v) { VARIANT src; HRESULT hr = S_OK; - BOOL handled = FALSE; VariantInit(&src); @@ -461,13 +381,9 @@ static inline HRESULT variant_from_dt(XDR_DT dt, xmlChar* str, VARIANT* v) case DT_UUID: { V_VT(v) = VT_BSTR; - V_BSTR(v) = bstr_from_xmlChar(str); - - if(!V_BSTR(v)) - return E_OUTOFMEMORY; - handled = TRUE; + V_BSTR(v) = SysAllocString(str); + return V_BSTR(v) ? S_OK : E_OUTOFMEMORY; } - break; case DT_DATE: case DT_DATE_TZ: case DT_DATETIME: @@ -485,7 +401,7 @@ static inline HRESULT variant_from_dt(XDR_DT dt, xmlChar* str, VARIANT* v) st.wDayOfWeek = st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0; V_VT(&src) = VT_BSTR; - V_BSTR(&src) = bstr_from_xmlChar(str); + V_BSTR(&src) = SysAllocString(str); if(!V_BSTR(&src)) return E_OUTOFMEMORY; @@ -527,7 +443,7 @@ static inline HRESULT variant_from_dt(XDR_DT dt, xmlChar* str, VARIANT* v) V_DATE(v) -= (DOUBLE)wcstol(p+1, NULL, 10)/24 + (DOUBLE)wcstol(p+4, NULL, 10)/1440; VariantClear(&src); - handled = TRUE; + return S_OK; } break; case DT_BIN_HEX: @@ -535,7 +451,7 @@ static inline HRESULT variant_from_dt(XDR_DT dt, xmlChar* str, VARIANT* v) SAFEARRAYBOUND sab; int i, len; - len = xmlStrlen(str)/2; + len = wcslen(str) / 2; sab.lLbound = 0; sab.cElements = len; @@ -548,13 +464,13 @@ static inline HRESULT variant_from_dt(XDR_DT dt, xmlChar* str, VARIANT* v) for(i=0; i<len; i++) ((BYTE*)V_ARRAY(v)->pvData)[i] = (hex_to_byte(str[2*i])<<4) + hex_to_byte(str[2*i+1]); - handled = TRUE; + return S_OK; } break; case DT_BIN_BASE64: { SAFEARRAYBOUND sab; - xmlChar *c1, *c2; + WCHAR *c1, *c2; int i, len; /* remove all formatting chars */ @@ -597,7 +513,7 @@ static inline HRESULT variant_from_dt(XDR_DT dt, xmlChar* str, VARIANT* v) ((BYTE*)V_ARRAY(v)->pvData)[3*i+2] = (base64_to_byte(str[4*i+2])<<6) + base64_to_byte(str[4*i+3]); } - handled = TRUE; + return S_OK; } break; case DT_BOOLEAN: @@ -648,102 +564,49 @@ static inline HRESULT variant_from_dt(XDR_DT dt, xmlChar* str, VARIANT* v) case DT_NOTATION: FIXME("need to handle dt:%s\n", debugstr_dt(dt)); V_VT(v) = VT_BSTR; - V_BSTR(v) = bstr_from_xmlChar(str); - if (!V_BSTR(v)) - return E_OUTOFMEMORY; - handled = TRUE; - break; + V_BSTR(v) = SysAllocString(str); + return V_BSTR(v) ? S_OK : E_OUTOFMEMORY; default: WARN("unknown type %d\n", dt); } - if (!handled) - { - V_VT(&src) = VT_BSTR; - V_BSTR(&src) = bstr_from_xmlChar(str); + V_VT(&src) = VT_BSTR; + V_BSTR(&src) = SysAllocString(str); - if(!V_BSTR(&src)) - return E_OUTOFMEMORY; + if (!V_BSTR(&src)) + return E_OUTOFMEMORY; - hr = VariantChangeTypeEx(v, &src, - MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT),0, V_VT(v)); - VariantClear(&src); - } + hr = VariantChangeTypeEx(v, &src, + MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT),0, V_VT(v)); + VariantClear(&src); return hr; } -static XDR_DT element_get_dt(xmlNodePtr node) +static HRESULT WINAPI domelem_get_nodeTypedValue(IXMLDOMElement *iface, VARIANT *v) { - XDR_DT dt = DT_INVALID; - - TRACE("(%p)\n", node); - if(node->type != XML_ELEMENT_NODE) - { - FIXME("invalid element node\n"); - return dt; - } - - if (node->ns && xmlStrEqual(node->ns->href, DT_nsURI)) - { - dt = str_to_dt(node->name, -1); - } - else - { - xmlChar* pVal = xmlGetNsProp(node, BAD_CAST "dt", DT_nsURI); - if (pVal) - { - dt = str_to_dt(pVal, -1); - xmlFree(pVal); - } - else if (node->doc) - { - IXMLDOMDocument3* doc = (IXMLDOMDocument3*)create_domdoc((xmlNodePtr)node->doc); - if (doc) - { - VARIANT v; - VariantInit(&v); - - if (IXMLDOMDocument3_get_schemas(doc, &v) == S_OK && - V_VT(&v) == VT_DISPATCH) - { - dt = SchemaCache_get_node_dt((IXMLDOMSchemaCollection2*)V_DISPATCH(&v), node); - } - VariantClear(&v); - IXMLDOMDocument3_Release(doc); - } - } - } - - TRACE("=> dt:%s\n", debugstr_dt(dt)); - return dt; -} - -static HRESULT WINAPI domelem_get_nodeTypedValue( - IXMLDOMElement *iface, - VARIANT* v) -{ - domelem *This = impl_from_IXMLDOMElement( iface ); - XDR_DT dt; - xmlChar* content; + domelem *element = impl_from_IXMLDOMElement(iface); HRESULT hr; + BSTR text; + XDR_DT dt; - TRACE("(%p)->(%p)\n", This, v); + TRACE("%p, %p.\n", iface, v); - if(!v) return E_INVALIDARG; + if (!v) + return E_INVALIDARG; V_VT(v) = VT_NULL; - dt = element_get_dt(get_element(This)); - + dt = node_get_data_type(element->node); if (dt == DT_INVALID) { - if (SUCCEEDED(hr = node_get_text(&This->node, &V_BSTR(v)))) - V_VT(v) = VT_BSTR; - return hr; + V_VT(v) = VT_BSTR; + hr = node_get_text(element->node, &V_BSTR(v)); + } + else if (SUCCEEDED(hr = node_get_preserved_text(element->node, &text))) + { + hr = variant_from_dt(dt, text, v); + SysFreeString(text); } - content = xmlNodeGetContent(get_element(This)); - hr = variant_from_dt(dt, content, v); - xmlFree(content); return hr; } @@ -832,17 +695,15 @@ static HRESULT encode_binhex(const BYTE *buf, int len, BSTR *ret) return S_OK; } -static HRESULT WINAPI domelem_put_nodeTypedValue( - IXMLDOMElement *iface, - VARIANT value) +static HRESULT WINAPI domelem_put_nodeTypedValue(IXMLDOMElement *iface, VARIANT value) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); XDR_DT dt; HRESULT hr; - TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + TRACE("%p, %s.\n", iface, debugstr_variant(&value)); - dt = element_get_dt(get_element(This)); + dt = node_get_data_type(element->node); switch (dt) { /* for untyped node coerce to BSTR and set */ @@ -855,16 +716,20 @@ static HRESULT WINAPI domelem_put_nodeTypedValue( hr = VariantChangeType(&content, &value, 0, VT_BSTR); if (hr == S_OK) { - hr = node_set_content(&This->node, V_BSTR(&content)); + hr = node_put_data(element->node, V_BSTR(&content)); VariantClear(&content); } } else - hr = node_set_content(&This->node, V_BSTR(&value)); + { + hr = node_put_data(element->node, V_BSTR(&value)); + } break; case DT_BIN_BASE64: if (V_VT(&value) == VT_BSTR) - hr = node_set_content(&This->node, V_BSTR(&value)); + { + hr = node_put_data(element->node, V_BSTR(&value)); + } else if (V_VT(&value) == (VT_UI1|VT_ARRAY)) { UINT dim = SafeArrayGetDim(V_ARRAY(&value)); @@ -888,7 +753,7 @@ static HRESULT WINAPI domelem_put_nodeTypedValue( SafeArrayUnaccessData(V_ARRAY(&value)); if (FAILED(hr)) return hr; - hr = node_set_content(&This->node, encoded); + hr = node_put_data(element->node, encoded); SysFreeString(encoded); } else @@ -921,7 +786,7 @@ static HRESULT WINAPI domelem_put_nodeTypedValue( SafeArrayUnaccessData(V_ARRAY(&value)); if (FAILED(hr)) return hr; - hr = node_set_content(&This->node, encoded); + hr = node_put_data(element->node, encoded); SysFreeString(encoded); } else @@ -938,19 +803,17 @@ static HRESULT WINAPI domelem_put_nodeTypedValue( return hr; } -static HRESULT WINAPI domelem_get_dataType( - IXMLDOMElement *iface, - VARIANT* typename) +static HRESULT WINAPI domelem_get_dataType(IXMLDOMElement *iface, VARIANT *typename) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); XDR_DT dt; - TRACE("(%p)->(%p)\n", This, typename); + TRACE("%p, %p.\n", iface, typename); if (!typename) return E_INVALIDARG; - dt = element_get_dt(get_element(This)); + dt = node_get_data_type(element->node); switch (dt) { case DT_BIN_BASE64: @@ -995,28 +858,29 @@ static HRESULT WINAPI domelem_get_dataType( return (V_VT(typename) != VT_NULL) ? S_OK : S_FALSE; } -static HRESULT WINAPI domelem_put_dataType( - IXMLDOMElement *iface, - BSTR dtName) +static HRESULT WINAPI domelem_put_dataType(IXMLDOMElement *iface, BSTR dtName) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); HRESULT hr = E_FAIL; - xmlChar *str; + BSTR text; XDR_DT dt; - TRACE("(%p)->(%s)\n", This, debugstr_w(dtName)); + TRACE("%p, %s.\n", iface, debugstr_w(dtName)); - if(dtName == NULL) + if (!dtName) return E_INVALIDARG; dt = bstr_to_dt(dtName, -1); + if (FAILED(hr = node_get_text(element->node, &text))) + return hr; + /* An example of this is. The Text in the node needs to be a 0 or 1 for a boolean type. This applies to changing types (string->bool) or setting a new one */ - str = xmlNodeGetContent(get_element(This)); - hr = dt_validate(dt, str); - xmlFree(str); + + hr = dt_validate(dt, text); + SysFreeString(text); /* Check all supported types. */ if (hr == S_OK) @@ -1053,29 +917,27 @@ static HRESULT WINAPI domelem_put_dataType( case DT_URI: case DT_UUID: { - xmlAttrPtr attr = xmlHasNsProp(get_element(This), DT_prefix, DT_nsURI); - if (attr) - { - attr = xmlSetNsProp(get_element(This), attr->ns, DT_prefix, dt_to_str(dt)); - hr = S_OK; - } - else + IXMLDOMNode *attr = NULL; + + if (SUCCEEDED(hr = create_attribute_node(L"dt:dt", L"urn:schemas-microsoft-com:datatypes", + element->node->owner, &attr))) { - xmlNsPtr ns = xmlNewNs(get_element(This), DT_nsURI, DT_prefix); - if (ns) + if ((text = SysAllocString(dt_to_bstr(dt)))) { - attr = xmlNewNsProp(get_element(This), ns, DT_prefix, dt_to_str(dt)); - if (attr) - { - xmlAddChild(get_element(This), (xmlNodePtr)attr); - hr = S_OK; - } - else - ERR("Failed to create Attribute\n"); + hr = IXMLDOMNode_put_text(attr, text); + SysFreeString(text); } else - ERR("Failed to create Namespace\n"); + { + hr = E_OUTOFMEMORY; + } } + + if (SUCCEEDED(hr)) + hr = node_set_attribute(element->node, attr, NULL); + + if (attr) + IXMLDOMNode_Release(attr); } break; default: @@ -1087,462 +949,161 @@ static HRESULT WINAPI domelem_put_dataType( return hr; } -static HRESULT WINAPI domelem_get_xml( - IXMLDOMElement *iface, - BSTR* p) +static HRESULT WINAPI domelem_get_xml(IXMLDOMElement *iface, BSTR *p) { - domelem *This = impl_from_IXMLDOMElement( iface ); + domelem *element = impl_from_IXMLDOMElement(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_xml(&This->node, TRUE, p); + return node_get_xml(element->node, p); } -static HRESULT WINAPI domelem_transformNode( - IXMLDOMElement *iface, - IXMLDOMNode *node, BSTR *p) +static HRESULT WINAPI domelem_transformNode(IXMLDOMElement *iface, IXMLDOMNode *node, BSTR *p) { - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%p %p)\n", This, node, p); - return node_transform_node(&This->node, node, p); -} + domelem *element = impl_from_IXMLDOMElement(iface); -static HRESULT WINAPI domelem_selectNodes( - IXMLDOMElement *iface, - BSTR p, IXMLDOMNodeList** outList) -{ - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); - return node_select_nodes(&This->node, p, outList); -} + TRACE("%p, %p, %p.\n", iface, node, p); -static HRESULT WINAPI domelem_selectSingleNode( - IXMLDOMElement *iface, - BSTR p, IXMLDOMNode** outNode) -{ - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); - return node_select_singlenode(&This->node, p, outNode); + return node_transform_node(element->node, node, p); } -static HRESULT WINAPI domelem_get_parsed( - IXMLDOMElement *iface, - VARIANT_BOOL* isParsed) +static HRESULT WINAPI domelem_selectNodes(IXMLDOMElement *iface, BSTR p, IXMLDOMNodeList **list) { - domelem *This = impl_from_IXMLDOMElement( iface ); - FIXME("(%p)->(%p) stub!\n", This, isParsed); - *isParsed = VARIANT_TRUE; - return S_OK; -} + domelem *element = impl_from_IXMLDOMElement(iface); -static HRESULT WINAPI domelem_get_namespaceURI( - IXMLDOMElement *iface, - BSTR* p) -{ - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_namespaceURI(&This->node, p); -} + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), list); -static HRESULT WINAPI domelem_get_prefix( - IXMLDOMElement *iface, - BSTR* prefix) -{ - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%p)\n", This, prefix); - return node_get_prefix( &This->node, prefix ); + return node_select_nodes(element->node, p, list); } -static HRESULT WINAPI domelem_get_baseName( - IXMLDOMElement *iface, - BSTR* name) +static HRESULT WINAPI domelem_selectSingleNode(IXMLDOMElement *iface, BSTR p, IXMLDOMNode **node) { - domelem *This = impl_from_IXMLDOMElement( iface ); - TRACE("(%p)->(%p)\n", This, name); - return node_get_base_name( &This->node, name ); -} + domelem *element = impl_from_IXMLDOMElement(iface); -static HRESULT WINAPI domelem_transformNodeToObject( - IXMLDOMElement *iface, - IXMLDOMNode* domNode, VARIANT var1) -{ - domelem *This = impl_from_IXMLDOMElement( iface ); - FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); - return E_NOTIMPL; + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), node); + + return node_select_singlenode(element->node, p, node); } -static HRESULT WINAPI domelem_get_tagName( - IXMLDOMElement *iface, - BSTR* p) +static HRESULT WINAPI domelem_get_parsed(IXMLDOMElement *iface, VARIANT_BOOL *v) { - domelem *This = impl_from_IXMLDOMElement( iface ); - xmlNodePtr element; - const xmlChar *prefix; - xmlChar *qname; - - TRACE("(%p)->(%p)\n", This, p ); - - if (!p) return E_INVALIDARG; - - element = get_element( This ); - if ( !element ) - return E_FAIL; - - prefix = element->ns ? element->ns->prefix : NULL; - qname = xmlBuildQName(element->name, prefix, NULL, 0); - - *p = bstr_from_xmlChar(qname); - if (qname != element->name) xmlFree(qname); + FIXME("%p, %p stub!\n", iface, v); - return *p ? S_OK : E_OUTOFMEMORY; + *v = VARIANT_TRUE; + return S_OK; } -static HRESULT WINAPI domelem_getAttribute( - IXMLDOMElement *iface, - BSTR name, VARIANT* value) +static HRESULT WINAPI domelem_get_namespaceURI(IXMLDOMElement *iface, BSTR *p) { - domelem *This = impl_from_IXMLDOMElement( iface ); - xmlNodePtr element; - xmlChar *xml_name, *xml_value = NULL; - xmlChar *local, *prefix; - HRESULT hr = S_FALSE; - xmlNsPtr ns; - - TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), value); - - if(!value || !name) - return E_INVALIDARG; - - element = get_element( This ); - if ( !element ) - return E_FAIL; - - V_BSTR(value) = NULL; - V_VT(value) = VT_NULL; - - xml_name = xmlchar_from_wchar( name ); - - if(!xmlValidateNameValue(xml_name)) - hr = E_FAIL; - else - { - if ((local = xmlSplitQName2(xml_name, &prefix))) - { - if (xmlStrEqual(prefix, BAD_CAST "xmlns")) - { - ns = xmlSearchNs(element->doc, element, local); - if (ns) - xml_value = xmlStrdup(ns->href); - } - else - { - ns = xmlSearchNs(element->doc, element, prefix); - if (ns) - xml_value = xmlGetNsProp(element, local, ns->href); - } - - xmlFree(prefix); - xmlFree(local); - } - else - xml_value = xmlGetNsProp(element, xml_name, NULL); - } + domelem *element = impl_from_IXMLDOMElement(iface); - free(xml_name); - if(xml_value) - { - V_VT(value) = VT_BSTR; - V_BSTR(value) = bstr_from_xmlChar( xml_value ); - xmlFree(xml_value); - hr = S_OK; - } + TRACE("%p, %p.\n", iface, p); - return hr; + return node_get_namespaceURI(element->node, p); } -static HRESULT WINAPI domelem_setAttribute( - IXMLDOMElement *iface, - BSTR name, VARIANT value) +static HRESULT WINAPI domelem_get_prefix(IXMLDOMElement *iface, BSTR *prefix) { - domelem *This = impl_from_IXMLDOMElement( iface ); - xmlChar *xml_name, *xml_value, *local, *prefix; - xmlNodePtr element; - HRESULT hr = S_OK; - - TRACE("(%p)->(%s %s)\n", This, debugstr_w(name), debugstr_variant(&value)); - - element = get_element( This ); - if ( !element ) - return E_FAIL; - - if (V_VT(&value) != VT_BSTR) - { - VARIANT var; - - VariantInit(&var); - hr = VariantChangeType(&var, &value, 0, VT_BSTR); - if (hr != S_OK) - { - FIXME("VariantChangeType failed\n"); - return hr; - } - - xml_value = xmlchar_from_wchar(V_BSTR(&var)); - VariantClear(&var); - } - else - xml_value = xmlchar_from_wchar(V_BSTR(&value)); - - xml_name = xmlchar_from_wchar( name ); - - if ((local = xmlSplitQName2(xml_name, &prefix))) - { - static const xmlChar* xmlnsA = (const xmlChar*)"xmlns"; - xmlNsPtr ns = NULL; - - /* it's not allowed to modify existing namespace definition */ - if (xmlStrEqual(prefix, xmlnsA)) - ns = xmlSearchNs(element->doc, element, local); - - xmlFree(prefix); - xmlFree(local); - - if (ns) - { - int cmp = xmlStrEqual(ns->href, xml_value); - free(xml_value); - free(xml_name); - return cmp ? S_OK : E_INVALIDARG; - } - } - - if (!xmlSetNsProp(element, NULL, xml_name, xml_value)) - hr = E_FAIL; + domelem *element = impl_from_IXMLDOMElement(iface); - free(xml_value); - free(xml_name); + TRACE("%p, %p.\n", iface, prefix); - return hr; + return node_get_prefix(element->node, prefix); } -static HRESULT WINAPI domelem_removeAttribute( - IXMLDOMElement *iface, - BSTR p) +static HRESULT WINAPI domelem_get_baseName(IXMLDOMElement *iface, BSTR *name) { - domelem *This = impl_from_IXMLDOMElement( iface ); - IXMLDOMNamedNodeMap *attr; - HRESULT hr; - - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - - hr = IXMLDOMElement_get_attributes(iface, &attr); - if (hr != S_OK) return hr; + domelem *element = impl_from_IXMLDOMElement(iface); - hr = IXMLDOMNamedNodeMap_removeNamedItem(attr, p, NULL); - IXMLDOMNamedNodeMap_Release(attr); + TRACE("%p, %p.\n", iface, name); - return hr; + return node_get_base_name(element->node, name); } -static HRESULT WINAPI domelem_getAttributeNode( - IXMLDOMElement *iface, - BSTR p, IXMLDOMAttribute** attributeNode ) +static HRESULT WINAPI domelem_transformNodeToObject(IXMLDOMElement *iface, IXMLDOMNode *node, VARIANT var) { - domelem *This = impl_from_IXMLDOMElement( iface ); - xmlChar *local, *prefix, *nameA; - HRESULT hr = S_FALSE; - xmlNodePtr element; - xmlAttrPtr attr; - - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), attributeNode); - - element = get_element( This ); - if (!element) return E_FAIL; - - if (attributeNode) *attributeNode = NULL; + FIXME("%p, %p, %s.\n", iface, node, debugstr_variant(&var)); - nameA = xmlchar_from_wchar(p); - if (!xmlValidateNameValue(nameA)) - { - free(nameA); - return E_FAIL; - } - - if (!attributeNode) - { - free(nameA); - return S_FALSE; - } - - *attributeNode = NULL; - - local = xmlSplitQName2(nameA, &prefix); - - if (local) - { - /* try to get namespace for supplied qualified name */ - xmlNsPtr ns = xmlSearchNs(element->doc, element, prefix); - xmlFree(prefix); - - attr = xmlHasNsProp(element, local, ns ? ns->href : NULL); - xmlFree(local); - } - else - { - attr = xmlHasProp(element, nameA); - /* attribute has attached namespace and we requested non-qualified - name - it's a failure case */ - if (attr && attr->ns) attr = NULL; - } + return E_NOTIMPL; +} - free(nameA); +static HRESULT WINAPI domelem_get_tagName(IXMLDOMElement *iface, BSTR *p) +{ + domelem *element = impl_from_IXMLDOMElement(iface); - if (attr) - { - IUnknown *unk = create_attribute((xmlNodePtr)attr, FALSE); - hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMAttribute, (void**)attributeNode); - IUnknown_Release(unk); - } + TRACE("%p, %p.\n", iface, p); - return hr; + return node_get_name(element->node, p); } -static HRESULT WINAPI domelem_setAttributeNode( - IXMLDOMElement *iface, - IXMLDOMAttribute* attribute, - IXMLDOMAttribute** old) +static HRESULT WINAPI domelem_getAttribute(IXMLDOMElement *iface, BSTR name, VARIANT *value) { - domelem *This = impl_from_IXMLDOMElement( iface ); - xmlChar *name, *value; - BSTR nameW, prefix; - xmlnode *attr_node; - xmlAttrPtr attr; - VARIANT valueW; - HRESULT hr; - - FIXME("(%p)->(%p %p): semi-stub\n", This, attribute, old); + domelem *element = impl_from_IXMLDOMElement(iface); - if (!attribute) return E_INVALIDARG; + TRACE("%p, %s, %p.\n", iface, debugstr_w(name), value); - attr_node = get_node_obj((IXMLDOMNode*)attribute); - if (!attr_node) return E_FAIL; + return node_get_attribute_value(element->node, name, value); +} - if (attr_node->parent) - { - WARN("attempt to add already used attribute\n"); - return E_FAIL; - } +static HRESULT WINAPI domelem_setAttribute(IXMLDOMElement *iface, BSTR name, VARIANT value) +{ + domelem *element = impl_from_IXMLDOMElement(iface); - hr = IXMLDOMAttribute_get_nodeName(attribute, &nameW); - if (hr != S_OK) return hr; + TRACE("%p, %s, %s.\n", iface, debugstr_w(name), debugstr_variant(&value)); - /* adding xmlns attribute doesn't change a tree or existing namespace definition */ - if (!wcscmp(nameW, L"xmlns")) - { - SysFreeString(nameW); - return DISP_E_UNKNOWNNAME; - } + return node_set_attribute_value(element->node, name, &value); +} - hr = IXMLDOMAttribute_get_nodeValue(attribute, &valueW); - if (hr != S_OK) - { - SysFreeString(nameW); - return hr; - } +static HRESULT WINAPI domelem_removeAttribute(IXMLDOMElement *iface, BSTR p) +{ + domelem *element = impl_from_IXMLDOMElement(iface); - if (old) *old = NULL; + TRACE("%p, %s.\n", iface, debugstr_w(p)); - TRACE("attribute: %s=%s\n", debugstr_w(nameW), debugstr_w(V_BSTR(&valueW))); + return node_remove_attribute(element->node, p, NULL); +} - hr = IXMLDOMAttribute_get_prefix(attribute, &prefix); - if (hr == S_OK) - { - FIXME("namespaces not supported: %s\n", debugstr_w(prefix)); - SysFreeString(prefix); - } +static HRESULT WINAPI domelem_getAttributeNode(IXMLDOMElement *iface, BSTR p, IXMLDOMAttribute **node) +{ + domelem *element = impl_from_IXMLDOMElement(iface); - name = xmlchar_from_wchar(nameW); - value = xmlchar_from_wchar(V_BSTR(&valueW)); + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), node); - if (!name || !value) - { - SysFreeString(nameW); - VariantClear(&valueW); - free(name); - free(value); - return E_OUTOFMEMORY; - } + return node_get_attribute(element->node, p, node); +} - attr = xmlSetNsProp(get_element(This), NULL, name, value); - if (attr) - attr_node->parent = (IXMLDOMNode*)iface; +static HRESULT WINAPI domelem_setAttributeNode(IXMLDOMElement *iface, IXMLDOMAttribute *attribute, IXMLDOMAttribute **old) +{ + domelem *element = impl_from_IXMLDOMElement(iface); - SysFreeString(nameW); - VariantClear(&valueW); - free(name); - free(value); + TRACE("%p, %p, %p\n", iface, attribute, old); - return attr ? S_OK : E_FAIL; + return node_set_attribute(element->node, (IXMLDOMNode *)attribute, (IXMLDOMNode **)old); } -static HRESULT WINAPI domelem_removeAttributeNode( - IXMLDOMElement *iface, - IXMLDOMAttribute* domAttribute, - IXMLDOMAttribute** attributeNode) +static HRESULT WINAPI domelem_removeAttributeNode(IXMLDOMElement *iface, + IXMLDOMAttribute *attribute, IXMLDOMAttribute **out_attribute) { - domelem *This = impl_from_IXMLDOMElement( iface ); - xmlnode *attr_node; - - TRACE("(%p)->(%p %p)\n", This, domAttribute, attributeNode); + domelem *element = impl_from_IXMLDOMElement(iface); - if (!domAttribute) - return E_INVALIDARG; - attr_node = get_node_obj((IXMLDOMNode*)domAttribute); - if (This->node.node != attr_node->node->parent) - return E_INVALIDARG; + TRACE("%p, %p, %p\n", iface, attribute, out_attribute); - if (attributeNode) - { - xmlUnlinkNode(attr_node->node ); - xmldoc_add_orphan(attr_node->node->doc, attr_node->node); - *attributeNode = (IXMLDOMAttribute*)create_node(attr_node->node); - } - else - { - if (xmlRemoveProp((xmlAttrPtr)attr_node->node) == -1) - return E_INVALIDARG; - } - return S_OK; + return node_remove_attribute_node(element->node, attribute, out_attribute); } -static HRESULT WINAPI domelem_getElementsByTagName( - IXMLDOMElement *iface, - BSTR tagName, IXMLDOMNodeList** resultList) +static HRESULT WINAPI domelem_getElementsByTagName(IXMLDOMElement *iface, BSTR name, IXMLDOMNodeList **list) { - domelem *This = impl_from_IXMLDOMElement( iface ); - xmlChar *query; - HRESULT hr; - BOOL XPath; - - TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList); - - if (!tagName || !resultList) return E_INVALIDARG; + domelem *element = impl_from_IXMLDOMElement(iface); - XPath = is_xpathmode(get_element(This)->doc); - set_xpathmode(get_element(This)->doc, TRUE); - query = tagName_to_XPath(tagName); - hr = create_selection(get_element(This), query, resultList); - xmlFree(query); - set_xpathmode(get_element(This)->doc, XPath); + TRACE("%p, %s, %p.\n", iface, debugstr_w(name), list); - return hr; + return node_get_elements_by_tagname(element->node, name, list); } -static HRESULT WINAPI domelem_normalize( - IXMLDOMElement *iface ) +static HRESULT WINAPI domelem_normalize(IXMLDOMElement *iface) { - domelem *This = impl_from_IXMLDOMElement( iface ); - FIXME("%p\n", This); + FIXME("%p.\n", iface); + return E_NOTIMPL; } @@ -1602,375 +1163,133 @@ static const struct IXMLDOMElementVtbl domelem_vtbl = domelem_normalize, }; -static HRESULT domelem_get_qualified_item(const xmlNodePtr node, BSTR name, BSTR uri, +static HRESULT domelem_get_qualified_item(const struct domnode *node, BSTR name, BSTR uri, IXMLDOMNode **item) { - xmlAttrPtr attr; - xmlChar *nameA; - xmlChar *href; - - TRACE("(%p)->(%s %s %p)\n", node, debugstr_w(name), debugstr_w(uri), item); - - if (!name || !item) return E_INVALIDARG; - - if (uri && *uri) - { - href = xmlchar_from_wchar(uri); - if (!href) return E_OUTOFMEMORY; - } - else - href = NULL; - - nameA = xmlchar_from_wchar(name); - if (!nameA) - { - free(href); - return E_OUTOFMEMORY; - } - - attr = xmlHasNsProp(node, nameA, href); - - free(nameA); - free(href); - - if (!attr) - { - *item = NULL; - return S_FALSE; - } + TRACE("%p, %s, %s, %p.\n", node, debugstr_w(name), debugstr_w(uri), item); - *item = create_node((xmlNodePtr)attr); + if (!name || !item) + return E_INVALIDARG; - return S_OK; + return node_get_qualified_attribute(node, name, uri, item); } -static HRESULT domelem_get_named_item(const xmlNodePtr node, BSTR name, IXMLDOMNode **item) +static HRESULT domelem_get_named_item(const struct domnode *node, BSTR name, IXMLDOMNode **item) { - xmlChar *nameA, *local, *prefix; - BSTR uriW, localW; - xmlNsPtr ns; - HRESULT hr; + TRACE("%p, %s, %p.\n", node, debugstr_w(name), item); - TRACE("(%p)->(%s %p)\n", node, debugstr_w(name), item ); - - nameA = xmlchar_from_wchar(name); - local = xmlSplitQName2(nameA, &prefix); - free(nameA); - - if (!local) - return domelem_get_qualified_item(node, name, NULL, item); - - /* try to get namespace uri for supplied qualified name */ - ns = xmlSearchNs(node->doc, node, prefix); - - xmlFree(prefix); - - if (!ns) - { - xmlFree(local); - if (item) *item = NULL; - return item ? S_FALSE : E_INVALIDARG; - } - - uriW = bstr_from_xmlChar(ns->href); - localW = bstr_from_xmlChar(local); - xmlFree(local); - - TRACE("got qualified node %s, uri=%s\n", debugstr_w(localW), debugstr_w(uriW)); - - hr = domelem_get_qualified_item(node, localW, uriW, item); - - SysFreeString(localW); - SysFreeString(uriW); + if (!name || !item) + return E_INVALIDARG; - return hr; + return node_get_attribute(node, name, (IXMLDOMAttribute **)item); } -static HRESULT domelem_set_named_item(xmlNodePtr node, IXMLDOMNode *newItem, IXMLDOMNode **namedItem) +static HRESULT domelem_set_named_item(struct domnode *node, IXMLDOMNode *newItem, IXMLDOMNode **namedItem) { - xmlNodePtr nodeNew; - xmlnode *ThisNew; - - TRACE("(%p)->(%p %p)\n", node, newItem, namedItem ); - - if(!newItem) - return E_INVALIDARG; - - if(namedItem) *namedItem = NULL; - - /* Must be an Attribute */ - ThisNew = get_node_obj( newItem ); - if(!ThisNew) return E_FAIL; - - if(ThisNew->node->type != XML_ATTRIBUTE_NODE) - return E_FAIL; + TRACE("%p, %p, %p.\n", node, newItem, namedItem ); - if(!ThisNew->node->parent) - if(xmldoc_remove_orphan(ThisNew->node->doc, ThisNew->node) != S_OK) - WARN("%p is not an orphan of %p\n", ThisNew->node, ThisNew->node->doc); - - nodeNew = xmlAddChild(node, ThisNew->node); - - if(namedItem) - *namedItem = create_node( nodeNew ); - return S_OK; + return node_set_attribute(node, newItem, namedItem); } -static HRESULT domelem_remove_qualified_item(xmlNodePtr node, BSTR name, BSTR uri, IXMLDOMNode **item) +static HRESULT domelem_remove_qualified_item(struct domnode *node, BSTR name, BSTR uri, IXMLDOMNode **item) { - xmlChar *nameA, *href; - xmlAttrPtr attr; - - TRACE("(%p)->(%s %s %p)\n", node, debugstr_w(name), debugstr_w(uri), item); + TRACE("%p, %s, %s, %p.\n", node, debugstr_w(name), debugstr_w(uri), item); if (!name) return E_INVALIDARG; - if (uri && *uri) - { - href = xmlchar_from_wchar(uri); - if (!href) return E_OUTOFMEMORY; - } - else - href = NULL; - - nameA = xmlchar_from_wchar(name); - if (!nameA) - { - free(href); - return E_OUTOFMEMORY; - } - - attr = xmlHasNsProp(node, nameA, href); - - free(nameA); - free(href); - - if (!attr) - { - if (item) *item = NULL; - return S_FALSE; - } - - if (item) - { - xmlUnlinkNode( (xmlNodePtr) attr ); - xmldoc_add_orphan( attr->doc, (xmlNodePtr) attr ); - *item = create_node( (xmlNodePtr) attr ); - } - else - { - if (xmlRemoveProp(attr) == -1) - ERR("xmlRemoveProp failed\n"); - } - - return S_OK; + return node_remove_qualified_attribute(node, name, uri, item); } -static HRESULT domelem_remove_named_item(xmlNodePtr node, BSTR name, IXMLDOMNode **item) +static HRESULT domelem_remove_named_item(struct domnode *node, BSTR name, IXMLDOMNode **item) { - xmlChar *nameA, *local, *prefix; - BSTR uriW, localW; - xmlNsPtr ns; - HRESULT hr; - - TRACE("(%p)->(%s %p)\n", node, debugstr_w(name), item); - - nameA = xmlchar_from_wchar(name); - local = xmlSplitQName2(nameA, &prefix); - free(nameA); - - if (!local) - return domelem_remove_qualified_item(node, name, NULL, item); - - ns = xmlSearchNs(node->doc, node, prefix); + TRACE("%p, %s, %p.\n", node, debugstr_w(name), item); - xmlFree(prefix); - - if (!ns) - { - xmlFree(local); - if (item) *item = NULL; - return item ? S_FALSE : E_INVALIDARG; - } - - uriW = bstr_from_xmlChar(ns->href); - localW = bstr_from_xmlChar(local); - xmlFree(local); - - TRACE("removing qualified node %s, uri=%s\n", debugstr_w(localW), debugstr_w(uriW)); - - hr = domelem_remove_qualified_item(node, localW, uriW, item); - - SysFreeString(localW); - SysFreeString(uriW); - - return hr; + return node_remove_attribute(node, name, item); } -static HRESULT domelem_get_item(const xmlNodePtr node, LONG index, IXMLDOMNode **item) +static HRESULT domelem_get_item(struct domnode *node, LONG index, IXMLDOMNode **item) { - xmlNsPtr ns, xmlns; - xmlAttrPtr curr; - LONG attrIndex; - IUnknown *unk; - HRESULT hr; - TRACE("%p, %ld, %p.\n", node, index, item); - *item = NULL; - - if (index < 0) - return S_FALSE; - - attrIndex = 0; - curr = node->properties; - if (curr) { - for (; attrIndex < index && curr->next != NULL; attrIndex++) - curr = curr->next; - - if (attrIndex == index) { - *item = create_node( (xmlNodePtr) curr ); - return S_OK; - } - - ++attrIndex; - } - - if (!node->nsDef) - return S_FALSE; - - ns = node->nsDef; - while (attrIndex < index) - { - attrIndex++; - - if (!ns->next) - break; - - ns = ns->next; - } - - if (attrIndex < index) - return S_FALSE; - - if (!ns->prefix) { - xmlns = NULL; - curr = xmlNewProp(NULL, BAD_CAST "xmlns", ns->href); - } else { - xmlns = xmlNewNs(NULL, BAD_CAST "http://www.w3.org/2000/xmlns/", BAD_CAST "xmlns"); - if (!xmlns) - return E_OUTOFMEMORY; - - curr = xmlNewNsProp(NULL, xmlns, ns->prefix, ns->href); - } - if (!curr) { - xmlFreeNs(xmlns); - return E_OUTOFMEMORY; - } - curr->doc = node->doc; - - unk = create_attribute((xmlNodePtr)curr, TRUE); - if (!unk) { - xmlFreeNs(xmlns); - xmlFreeProp(curr); - return E_OUTOFMEMORY; - } - - hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)item); - IUnknown_Release(unk); - - return hr; + return node_get_attribute_by_index(node, index, item); } -static HRESULT domelem_get_length(const xmlNodePtr node, LONG *length) +static HRESULT domelem_get_length(struct domnode *node, LONG *length) { - xmlAttrPtr curr; - LONG attrCount; - xmlNsPtr ns; - - TRACE("(%p)->(%p)\n", node, length); + TRACE("%p, %p.\n", node, length); - if( !length ) + if (!length) return E_INVALIDARG; - attrCount = 0; - curr = node->properties; - while (curr) { - attrCount++; - curr = curr->next; - } - - ns = node->nsDef; - while (ns) { - attrCount++; - ns = ns->next; - } - *length = attrCount; - + *length = list_count(&node->attributes); return S_OK; } -static HRESULT domelem_next_node(const xmlNodePtr node, LONG *iter, IXMLDOMNode **nextNode) +static HRESULT domelem_next_node(const struct domnode *node, LONG *iter, IXMLDOMNode **nextNode) { - xmlAttrPtr curr; - LONG i; + struct domnode *curr = NULL, *n; + LONG count = *iter; TRACE("%p, %ld, %p.\n", node, *iter, nextNode); *nextNode = NULL; - curr = node->properties; - if (curr == NULL) - return S_FALSE; - - for (i = 0; i < *iter; i++) { - if (curr->next == NULL) - return S_FALSE; - else - curr = curr->next; + LIST_FOR_EACH_ENTRY(n, &node->attributes, struct domnode, entry) + { + curr = n; + if (!count--) break; + curr = NULL; } - (*iter)++; - *nextNode = create_node((xmlNodePtr)curr); + if (!curr) + return S_FALSE; - return S_OK; + (*iter)++; + return create_node(curr, nextNode); } -static const struct nodemap_funcs domelem_attr_map = { - domelem_get_named_item, - domelem_set_named_item, - domelem_remove_named_item, - domelem_get_item, - domelem_get_length, - domelem_get_qualified_item, - domelem_remove_qualified_item, - domelem_next_node +static const struct nodemap_funcs domelem_attr_map = +{ + .get_named_item = domelem_get_named_item, + .set_named_item = domelem_set_named_item, + .remove_named_item = domelem_remove_named_item, + .get_item = domelem_get_item, + .get_length = domelem_get_length, + .get_qualified_item = domelem_get_qualified_item, + .remove_qualified_item = domelem_remove_qualified_item, + .next_node = domelem_next_node, }; -static const tid_t domelem_iface_tids[] = { +static const tid_t domelem_iface_tids[] = +{ IXMLDOMElement_tid, 0 }; -static dispex_static_data_t domelem_dispex = { +static dispex_static_data_t domelem_dispex = +{ NULL, IXMLDOMElement_tid, NULL, domelem_iface_tids }; -IUnknown* create_element( xmlNodePtr element ) +HRESULT create_element(struct domnode *node, IUnknown **obj) { - domelem *This; + domelem *object; + + *obj = NULL; - This = malloc(sizeof *This); - if ( !This ) - return NULL; + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IXMLDOMElement_iface.lpVtbl = &domelem_vtbl; + object->refcount = 1; + object->node = domnode_addref(node); - This->IXMLDOMElement_iface.lpVtbl = &domelem_vtbl; - This->ref = 1; + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMElement_iface, &domelem_dispex); - init_xmlnode(&This->node, element, (IXMLDOMNode*)&This->IXMLDOMElement_iface, &domelem_dispex); + *obj = (IUnknown *)&object->IXMLDOMElement_iface; - return (IUnknown*)&This->IXMLDOMElement_iface; + return S_OK; } diff --git a/dlls/msxml3/entityref.c b/dlls/msxml3/entityref.c index d9947428964..ab26064ff6e 100644 --- a/dlls/msxml3/entityref.c +++ b/dlls/msxml3/entityref.c @@ -21,8 +21,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> #include "windef.h" #include "winbase.h" @@ -38,12 +36,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); typedef struct _entityref { - xmlnode node; + DispatchEx dispex; IXMLDOMEntityReference IXMLDOMEntityReference_iface; - LONG ref; + LONG refcount; + struct domnode *node; } entityref; -static const tid_t domentityref_se_tids[] = { +static const tid_t domentityref_se_tids[] = +{ IXMLDOMNode_tid, IXMLDOMEntityReference_tid, NULL_tid @@ -54,463 +54,395 @@ static inline entityref *impl_from_IXMLDOMEntityReference( IXMLDOMEntityReferenc return CONTAINING_RECORD(iface, entityref, IXMLDOMEntityReference_iface); } -static HRESULT WINAPI entityref_QueryInterface( - IXMLDOMEntityReference *iface, - REFIID riid, - void** ppvObject ) +static HRESULT WINAPI entityref_QueryInterface(IXMLDOMEntityReference *iface, REFIID riid, void **obj) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + entityref *ref = impl_from_IXMLDOMEntityReference( iface ); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); - if ( IsEqualGUID( riid, &IID_IXMLDOMEntityReference ) || - IsEqualGUID( riid, &IID_IXMLDOMNode ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IUnknown ) ) + if (IsEqualGUID(riid, &IID_IXMLDOMEntityReference) || + IsEqualGUID(riid, &IID_IXMLDOMNode) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IUnknown) ) + { + *obj = iface; + } + else if (dispex_query_interface(&ref->dispex, riid, obj)) { - *ppvObject = iface; + return *obj ? S_OK : E_NOINTERFACE; } - else if(node_query_interface(&This->node, riid, ppvObject)) + else if (node_query_interface(ref->node, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } - else if (IsEqualGUID( riid, &IID_ISupportErrorInfo )) + else if (IsEqualGUID(riid, &IID_ISupportErrorInfo)) { - return node_create_supporterrorinfo(domentityref_se_tids, ppvObject); + return node_create_supporterrorinfo(domentityref_se_tids, obj); } else { TRACE("Unsupported interface %s\n", debugstr_guid(riid)); - *ppvObject = NULL; + *obj = NULL; return E_NOINTERFACE; } - IUnknown_AddRef((IUnknown*)*ppvObject); + IUnknown_AddRef((IUnknown *)*obj); return S_OK; } -static ULONG WINAPI entityref_AddRef( - IXMLDOMEntityReference *iface ) +static ULONG WINAPI entityref_AddRef(IXMLDOMEntityReference *iface) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - ULONG ref = InterlockedIncrement( &This->ref ); - TRACE("%p, refcount %lu.\n", iface, ref); - return ref; + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + ULONG refcount = InterlockedIncrement(&ref->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); + + return refcount; } -static ULONG WINAPI entityref_Release( - IXMLDOMEntityReference *iface ) +static ULONG WINAPI entityref_Release(IXMLDOMEntityReference *iface) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - ULONG ref = InterlockedDecrement( &This->ref ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + ULONG refcount = InterlockedDecrement(&ref->refcount); - TRACE("%p, refcount %lu.\n", iface, ref); + TRACE("%p, refcount %lu.\n", iface, refcount); - if (!ref) + if (!refcount) { - destroy_xmlnode(&This->node); - free(This); + domnode_release(ref->node); + free(ref); } - return ref; + return refcount; } -static HRESULT WINAPI entityref_GetTypeInfoCount( - IXMLDOMEntityReference *iface, - UINT* pctinfo ) +static HRESULT WINAPI entityref_GetTypeInfoCount(IXMLDOMEntityReference *iface, UINT *count) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + return IDispatchEx_GetTypeInfoCount(&ref->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI entityref_GetTypeInfo( - IXMLDOMEntityReference *iface, - UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI entityref_GetTypeInfo(IXMLDOMEntityReference *iface, UINT index, LCID lcid, ITypeInfo **ti) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + return IDispatchEx_GetTypeInfo(&ref->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI entityref_GetIDsOfNames( - IXMLDOMEntityReference *iface, - REFIID riid, LPOLESTR* rgszNames, - UINT cNames, LCID lcid, DISPID* rgDispId ) +static HRESULT WINAPI entityref_GetIDsOfNames(IXMLDOMEntityReference *iface, REFIID riid, LPOLESTR* rgszNames, + UINT cNames, LCID lcid, DISPID* rgDispId ) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, - riid, rgszNames, cNames, lcid, rgDispId); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + return IDispatchEx_GetIDsOfNames(&ref->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); } -static HRESULT WINAPI entityref_Invoke( - IXMLDOMEntityReference *iface, - DISPID dispIdMember, REFIID riid, LCID lcid, - WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr ) +static HRESULT WINAPI entityref_Invoke(IXMLDOMEntityReference *iface, DISPID dispIdMember, REFIID riid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *puArgErr) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + return IDispatchEx_Invoke(&ref->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, flags, params, result, ei, puArgErr); } -static HRESULT WINAPI entityref_get_nodeName( - IXMLDOMEntityReference *iface, - BSTR* p ) +static HRESULT WINAPI entityref_get_nodeName(IXMLDOMEntityReference *iface, BSTR *p) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); - FIXME("(%p)->(%p)\n", This, p); + FIXME("%p, %p.\n", iface, p); - return node_get_nodeName(&This->node, p); + return node_get_name(ref->node, p); } -static HRESULT WINAPI entityref_get_nodeValue( - IXMLDOMEntityReference *iface, - VARIANT* value) +static HRESULT WINAPI entityref_get_nodeValue(IXMLDOMEntityReference *iface, VARIANT *value) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%p)\n", This, value); + TRACE("%p, %p.\n", iface, value); + return return_null_var(value); } -static HRESULT WINAPI entityref_put_nodeValue( - IXMLDOMEntityReference *iface, - VARIANT value) +static HRESULT WINAPI entityref_put_nodeValue(IXMLDOMEntityReference *iface, VARIANT value) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + TRACE("%p, %s.\n", iface, debugstr_variant(&value)); + return E_FAIL; } -static HRESULT WINAPI entityref_get_nodeType( - IXMLDOMEntityReference *iface, - DOMNodeType* domNodeType ) +static HRESULT WINAPI entityref_get_nodeType(IXMLDOMEntityReference *iface, DOMNodeType *type) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - - TRACE("(%p)->(%p)\n", This, domNodeType); + TRACE("%p, %p.\n", iface, type); - *domNodeType = NODE_ENTITY_REFERENCE; + *type = NODE_ENTITY_REFERENCE; return S_OK; } -static HRESULT WINAPI entityref_get_parentNode( - IXMLDOMEntityReference *iface, - IXMLDOMNode** parent ) +static HRESULT WINAPI entityref_get_parentNode(IXMLDOMEntityReference *iface, IXMLDOMNode **parent) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); - TRACE("(%p)->(%p)\n", This, parent); + TRACE("%p, %p.\n", iface, parent); - return node_get_parent(&This->node, parent); + return node_get_parent(ref->node, parent); } -static HRESULT WINAPI entityref_get_childNodes( - IXMLDOMEntityReference *iface, - IXMLDOMNodeList** outList) +static HRESULT WINAPI entityref_get_childNodes(IXMLDOMEntityReference *iface, IXMLDOMNodeList **list) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); - TRACE("(%p)->(%p)\n", This, outList); + TRACE("%p, %p.\n", iface, list); - return node_get_child_nodes(&This->node, outList); + return node_get_child_nodes(ref->node, list); } -static HRESULT WINAPI entityref_get_firstChild( - IXMLDOMEntityReference *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI entityref_get_firstChild(IXMLDOMEntityReference *iface, IXMLDOMNode **node) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_first_child(&This->node, domNode); + return node_get_first_child(ref->node, node); } -static HRESULT WINAPI entityref_get_lastChild( - IXMLDOMEntityReference *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI entityref_get_lastChild(IXMLDOMEntityReference *iface, IXMLDOMNode **node) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_last_child(&This->node, domNode); + return node_get_last_child(ref->node, node); } -static HRESULT WINAPI entityref_get_previousSibling( - IXMLDOMEntityReference *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI entityref_get_previousSibling(IXMLDOMEntityReference *iface, IXMLDOMNode **node) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_previous_sibling(&This->node, domNode); + return node_get_previous_sibling(ref->node, node); } -static HRESULT WINAPI entityref_get_nextSibling( - IXMLDOMEntityReference *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI entityref_get_nextSibling(IXMLDOMEntityReference *iface, IXMLDOMNode **node) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_next_sibling(&This->node, domNode); + return node_get_next_sibling(ref->node, node); } -static HRESULT WINAPI entityref_get_attributes( - IXMLDOMEntityReference *iface, - IXMLDOMNamedNodeMap** attributeMap) +static HRESULT WINAPI entityref_get_attributes(IXMLDOMEntityReference *iface, IXMLDOMNamedNodeMap **map) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + TRACE("%p, %p.\n", iface, map); - TRACE("(%p)->(%p)\n", This, attributeMap); - - return return_null_ptr((void**)attributeMap); + return return_null_ptr((void **)map); } -static HRESULT WINAPI entityref_insertBefore( - IXMLDOMEntityReference *iface, - IXMLDOMNode* newNode, VARIANT refChild, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI entityref_insertBefore(IXMLDOMEntityReference *iface, + IXMLDOMNode* newNode, VARIANT refChild, IXMLDOMNode** outOldNode) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); - FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode); + FIXME("%p, %p, %s, %p needs test\n", iface, newNode, debugstr_variant(&refChild), outOldNode); - return node_insert_before(&This->node, newNode, &refChild, outOldNode); + return node_insert_before(ref->node, newNode, &refChild, outOldNode); } -static HRESULT WINAPI entityref_replaceChild( - IXMLDOMEntityReference *iface, - IXMLDOMNode* newNode, - IXMLDOMNode* oldNode, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI entityref_replaceChild(IXMLDOMEntityReference *iface, + IXMLDOMNode* newNode, IXMLDOMNode* oldNode, IXMLDOMNode** outOldNode) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); - FIXME("(%p)->(%p %p %p) needs test\n", This, newNode, oldNode, outOldNode); + FIXME("%p, %p, %p, %p needs test\n", iface, newNode, oldNode, outOldNode); - return node_replace_child(&This->node, newNode, oldNode, outOldNode); + return node_replace_child(ref->node, newNode, oldNode, outOldNode); } -static HRESULT WINAPI entityref_removeChild( - IXMLDOMEntityReference *iface, - IXMLDOMNode *child, IXMLDOMNode **oldChild) +static HRESULT WINAPI entityref_removeChild(IXMLDOMEntityReference *iface, + IXMLDOMNode *child, IXMLDOMNode **oldChild) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%p %p)\n", This, child, oldChild); - return node_remove_child(&This->node, child, oldChild); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + + TRACE("%p, %p, %p.\n", iface, child, oldChild); + + return node_remove_child(ref->node, child, oldChild); } -static HRESULT WINAPI entityref_appendChild( - IXMLDOMEntityReference *iface, - IXMLDOMNode *child, IXMLDOMNode **outChild) +static HRESULT WINAPI entityref_appendChild(IXMLDOMEntityReference *iface, + IXMLDOMNode *child, IXMLDOMNode **outChild) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%p %p)\n", This, child, outChild); - return node_append_child(&This->node, child, outChild); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + + TRACE("%p, %p, %p.\n", iface, child, outChild); + + return node_append_child(ref->node, child, outChild); } -static HRESULT WINAPI entityref_hasChildNodes( - IXMLDOMEntityReference *iface, - VARIANT_BOOL *ret) +static HRESULT WINAPI entityref_hasChildNodes(IXMLDOMEntityReference *iface, VARIANT_BOOL *ret) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%p)\n", This, ret); - return node_has_childnodes(&This->node, ret); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + + TRACE("%p, %p.\n", iface, ret); + + return node_has_childnodes(ref->node, ret); } -static HRESULT WINAPI entityref_get_ownerDocument( - IXMLDOMEntityReference *iface, - IXMLDOMDocument **doc) +static HRESULT WINAPI entityref_get_ownerDocument(IXMLDOMEntityReference *iface, IXMLDOMDocument **doc) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%p)\n", This, doc); - return node_get_owner_doc(&This->node, doc); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + + TRACE("%p, %p.\n", iface, doc); + + return node_get_owner_document(ref->node, doc); } -static HRESULT WINAPI entityref_cloneNode( - IXMLDOMEntityReference *iface, - VARIANT_BOOL deep, IXMLDOMNode** outNode) +static HRESULT WINAPI entityref_cloneNode(IXMLDOMEntityReference *iface, VARIANT_BOOL deep, IXMLDOMNode **node) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%d %p)\n", This, deep, outNode); - return node_clone( &This->node, deep, outNode ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + + TRACE("%p, %d, %p.\n", iface, deep, node); + + return node_clone(ref->node, deep, node); } -static HRESULT WINAPI entityref_get_nodeTypeString( - IXMLDOMEntityReference *iface, - BSTR* p) +static HRESULT WINAPI entityref_get_nodeTypeString(IXMLDOMEntityReference *iface, BSTR *p) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"entityreference", p); } -static HRESULT WINAPI entityref_get_text( - IXMLDOMEntityReference *iface, - BSTR* p) +static HRESULT WINAPI entityref_get_text(IXMLDOMEntityReference *iface, BSTR *p) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_text(&This->node, p); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_text(ref->node, p); } -static HRESULT WINAPI entityref_put_text( - IXMLDOMEntityReference *iface, - BSTR p) +static HRESULT WINAPI entityref_put_text(IXMLDOMEntityReference *iface, BSTR p) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - return node_put_text( &This->node, p ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(p)); + + return node_put_data(ref->node, p); } -static HRESULT WINAPI entityref_get_specified( - IXMLDOMEntityReference *iface, - VARIANT_BOOL* isSpecified) +static HRESULT WINAPI entityref_get_specified(IXMLDOMEntityReference *iface, VARIANT_BOOL *v) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - FIXME("(%p)->(%p) stub!\n", This, isSpecified); - *isSpecified = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI entityref_get_definition( - IXMLDOMEntityReference *iface, - IXMLDOMNode** definitionNode) +static HRESULT WINAPI entityref_get_definition(IXMLDOMEntityReference *iface, IXMLDOMNode **node) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - FIXME("(%p)->(%p)\n", This, definitionNode); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI entityref_get_nodeTypedValue( - IXMLDOMEntityReference *iface, - VARIANT* var1) +static HRESULT WINAPI entityref_get_nodeTypedValue(IXMLDOMEntityReference *iface, VARIANT *v) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - FIXME("(%p)->(%p)\n", This, var1); - return return_null_var(var1); + FIXME("%p, %p.\n", iface, v); + + return return_null_var(v); } -static HRESULT WINAPI entityref_put_nodeTypedValue( - IXMLDOMEntityReference *iface, - VARIANT typedValue) +static HRESULT WINAPI entityref_put_nodeTypedValue(IXMLDOMEntityReference *iface, VARIANT v) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); + FIXME("%p, %s.\n", iface, debugstr_variant(&v)); + return E_NOTIMPL; } -static HRESULT WINAPI entityref_get_dataType( - IXMLDOMEntityReference *iface, - VARIANT* typename) +static HRESULT WINAPI entityref_get_dataType(IXMLDOMEntityReference *iface, VARIANT *v) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - FIXME("(%p)->(%p): should return a valid value\n", This, typename); - return return_null_var( typename ); + FIXME("%p, %p: should return a valid value\n", iface, v); + + return return_null_var(v); } -static HRESULT WINAPI entityref_put_dataType( - IXMLDOMEntityReference *iface, - BSTR p) +static HRESULT WINAPI entityref_put_dataType(IXMLDOMEntityReference *iface, BSTR p) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + TRACE("%p, %s.\n", iface, debugstr_w(p)); - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - - if(!p) + if (!p) return E_INVALIDARG; return E_FAIL; } -static HRESULT WINAPI entityref_get_xml( - IXMLDOMEntityReference *iface, - BSTR* p) +static HRESULT WINAPI entityref_get_xml(IXMLDOMEntityReference *iface, BSTR *p) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_xml(&This->node, FALSE, p); + return node_get_xml(ref->node, p); } -static HRESULT WINAPI entityref_transformNode( - IXMLDOMEntityReference *iface, - IXMLDOMNode *node, BSTR *p) +static HRESULT WINAPI entityref_transformNode(IXMLDOMEntityReference *iface, IXMLDOMNode *node, BSTR *p) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%p %p)\n", This, node, p); - return node_transform_node(&This->node, node, p); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + + TRACE("%p, %p, %p.\n", iface, node, p); + + return node_transform_node(ref->node, node, p); } -static HRESULT WINAPI entityref_selectNodes( - IXMLDOMEntityReference *iface, - BSTR p, IXMLDOMNodeList** outList) +static HRESULT WINAPI entityref_selectNodes(IXMLDOMEntityReference *iface, BSTR p, IXMLDOMNodeList **list) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); - return node_select_nodes(&This->node, p, outList); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), list); + + return node_select_nodes(ref->node, p, list); } -static HRESULT WINAPI entityref_selectSingleNode( - IXMLDOMEntityReference *iface, - BSTR p, IXMLDOMNode** outNode) +static HRESULT WINAPI entityref_selectSingleNode(IXMLDOMEntityReference *iface, BSTR p, IXMLDOMNode **node) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); - return node_select_singlenode(&This->node, p, outNode); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), node); + + return node_select_singlenode(ref->node, p, node); } -static HRESULT WINAPI entityref_get_parsed( - IXMLDOMEntityReference *iface, - VARIANT_BOOL* isParsed) +static HRESULT WINAPI entityref_get_parsed(IXMLDOMEntityReference *iface, VARIANT_BOOL *v) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - FIXME("(%p)->(%p) stub!\n", This, isParsed); - *isParsed = VARIANT_TRUE; + FIXME("%p, %p: stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI entityref_get_namespaceURI( - IXMLDOMEntityReference *iface, - BSTR* p) +static HRESULT WINAPI entityref_get_namespaceURI(IXMLDOMEntityReference *iface, BSTR *p) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_namespaceURI(&This->node, p); + entityref *ref = impl_from_IXMLDOMEntityReference(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_namespaceURI(ref->node, p); } -static HRESULT WINAPI entityref_get_prefix( - IXMLDOMEntityReference *iface, - BSTR* prefix) +static HRESULT WINAPI entityref_get_prefix(IXMLDOMEntityReference *iface, BSTR *prefix) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - FIXME("(%p)->(%p): stub\n", This, prefix); - return return_null_bstr( prefix ); + FIXME("%p, %p: stub\n", iface, prefix); + + return return_null_bstr(prefix); } -static HRESULT WINAPI entityref_get_baseName( - IXMLDOMEntityReference *iface, - BSTR* name) +static HRESULT WINAPI entityref_get_baseName(IXMLDOMEntityReference *iface, BSTR *name) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - FIXME("(%p)->(%p): needs test\n", This, name); - return return_null_bstr( name ); + FIXME("%p, %p: needs test\n", iface, name); + + return return_null_bstr(name); } -static HRESULT WINAPI entityref_transformNodeToObject( - IXMLDOMEntityReference *iface, - IXMLDOMNode* domNode, VARIANT var1) +static HRESULT WINAPI entityref_transformNodeToObject(IXMLDOMEntityReference *iface, IXMLDOMNode *node, VARIANT var1) { - entityref *This = impl_from_IXMLDOMEntityReference( iface ); - FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); + FIXME("%p, %p, %s.\n", iface, node, debugstr_variant(&var1)); + return E_NOTIMPL; } @@ -561,30 +493,36 @@ static const struct IXMLDOMEntityReferenceVtbl entityref_vtbl = entityref_transformNodeToObject, }; -static const tid_t domentityref_iface_tids[] = { +static const tid_t domentityref_iface_tids[] = +{ IXMLDOMEntityReference_tid, 0 }; -static dispex_static_data_t domentityref_dispex = { +static dispex_static_data_t domentityref_dispex = +{ NULL, IXMLDOMEntityReference_tid, NULL, domentityref_iface_tids }; -IUnknown* create_doc_entity_ref( xmlNodePtr entity ) +HRESULT create_entity_ref(struct domnode *node, IUnknown **obj) { - entityref *This; + entityref *object; - This = malloc(sizeof(*This)); - if ( !This ) - return NULL; + *obj = NULL; - This->IXMLDOMEntityReference_iface.lpVtbl = &entityref_vtbl; - This->ref = 1; + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; - init_xmlnode(&This->node, entity, (IXMLDOMNode*)&This->IXMLDOMEntityReference_iface, &domentityref_dispex); + object->IXMLDOMEntityReference_iface.lpVtbl = &entityref_vtbl; + object->refcount = 1; + object->node = domnode_addref(node); - return (IUnknown*)&This->IXMLDOMEntityReference_iface; + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMEntityReference_iface, &domentityref_dispex); + + *obj = (IUnknown *)&object->IXMLDOMEntityReference_iface; + + return S_OK; } diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 9709f8247ab..66d576c709d 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -123,26 +123,114 @@ struct xslprocessor_params extern void schemasInit(void); extern void schemasCleanup(void); -/* IXMLDOMNode Internal Structure */ -typedef struct _xmlnode +struct dom_namespace { - DispatchEx dispex; - IXMLDOMNode *iface; - IXMLDOMNode *parent; - xmlNodePtr node; -} xmlnode; + struct list entry; + BSTR qname; + BSTR name; + BSTR uri; +}; + +enum domnode_flags +{ + DOMNODE_READONLY_VALUE = 0x1, + DOMNODE_IGNORED_WS_AFTER_STARTTAG = 0x2, + DOMNODE_IGNORED_WS = 0x4, +}; + +typedef struct _select_ns_entry +{ + struct list entry; + xmlChar const* prefix; + xmlChar prefix_end; + xmlChar const* href; + xmlChar href_end; +} select_ns_entry; + +struct domdoc_properties +{ + MSXML_VERSION version; + VARIANT_BOOL preserving; + VARIANT_BOOL validating; + IXMLDOMSchemaCollection2* schemaCache; + struct list selectNsList; + xmlChar const* selectNsStr; + LONG selectNsStr_len; + BOOL XPath; + IUri *uri; +}; + +struct domnode +{ + struct list entry; + struct list owner_entry; + unsigned int refcount; + + DOMNodeType type; + unsigned int flags; + + BSTR name; + BSTR prefix; + BSTR qname; + BSTR data; + BSTR uri; + + struct domdoc_properties *properties; + + struct domnode *parent; + struct domnode *owner; + struct list children; + struct list attributes; + struct list namespaces; + struct list owned; +}; + +extern IXMLDOMSchemaCollection2 *doc_properties_get_schema(struct domdoc_properties *properties); +extern MSXML_VERSION doc_properties_get_version(struct domdoc_properties *properties); + +extern void domdoc_properties_clear_selection_namespaces(struct list *); +extern struct domdoc_properties *domdoc_create_properties(MSXML_VERSION version); +extern MSXML_VERSION domdoc_version(const struct domnode *doc); +extern HRESULT domnode_create(DOMNodeType type, const WCHAR *name, int name_len, + const WCHAR *uri, int uri_len, struct domnode *owner, struct domnode **node); +extern void domnode_destroy_tree(struct domnode *tree); +extern struct domnode *domnode_addref(struct domnode *node); +extern void domnode_release(struct domnode *node); +extern struct domnode *domnode_get_first_child(struct domnode *node); +extern struct domnode *domnode_get_next_sibling(struct domnode *node); +extern HRESULT domnode_get_attribute(const struct domnode *node, const WCHAR *name, struct domnode **attr); +extern HRESULT node_clone_domnode(struct domnode *, bool, struct domnode **); +extern HRESULT parse_stream(ISequentialStream *stream, bool utf16, VARIANT_BOOL preserve, struct domnode **tree); +extern void dump_doc_refcounts(struct domnode *node); + +struct parsed_name +{ + BSTR prefix; + BSTR local; + BSTR qname; +}; + +extern HRESULT parse_qualified_name(const WCHAR *src, struct parsed_name *name); +void parsed_name_cleanup(struct parsed_name *name); + +/* Compat glue */ +extern xmlDocPtr create_xmldoc_from_domdoc(struct domnode *node, xmlNodePtr *xmlnode); +static inline bool xml_is_space(WCHAR ch) +{ + return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; +} /* IXMLDOMNamedNodeMap custom function table */ struct nodemap_funcs { - HRESULT (*get_named_item)(const xmlNodePtr,BSTR,IXMLDOMNode**); - HRESULT (*set_named_item)(xmlNodePtr,IXMLDOMNode*,IXMLDOMNode**); - HRESULT (*remove_named_item)(xmlNodePtr,BSTR,IXMLDOMNode**); - HRESULT (*get_item)(xmlNodePtr,LONG,IXMLDOMNode**); - HRESULT (*get_length)(xmlNodePtr,LONG*); - HRESULT (*get_qualified_item)(const xmlNodePtr,BSTR,BSTR,IXMLDOMNode**); - HRESULT (*remove_qualified_item)(xmlNodePtr,BSTR,BSTR,IXMLDOMNode**); - HRESULT (*next_node)(const xmlNodePtr,LONG*,IXMLDOMNode**); + HRESULT (*get_named_item)(const struct domnode *,BSTR,IXMLDOMNode**); + HRESULT (*set_named_item)(struct domnode *,IXMLDOMNode*,IXMLDOMNode**); + HRESULT (*remove_named_item)(struct domnode *,BSTR,IXMLDOMNode**); + HRESULT (*get_item)(struct domnode *,LONG,IXMLDOMNode**); + HRESULT (*get_length)(struct domnode *,LONG*); + HRESULT (*get_qualified_item)(const struct domnode *,BSTR,BSTR,IXMLDOMNode**); + HRESULT (*remove_qualified_item)(struct domnode *,BSTR,BSTR,IXMLDOMNode**); + HRESULT (*next_node)(const struct domnode *,LONG *,IXMLDOMNode **); }; /* used by IEnumVARIANT to access outer object items */ @@ -153,44 +241,25 @@ struct enumvariant_funcs }; /* constructors */ -extern IUnknown *create_domdoc( xmlNodePtr ); -extern IUnknown *create_xmldoc( void ); -extern IXMLDOMNode *create_node( xmlNodePtr ); -extern IUnknown *create_element( xmlNodePtr ); -extern IUnknown *create_attribute( xmlNodePtr, BOOL ); -extern IUnknown *create_text( xmlNodePtr ); -extern IUnknown *create_pi( xmlNodePtr ); -extern IUnknown *create_comment( xmlNodePtr ); -extern IUnknown *create_cdata( xmlNodePtr ); -extern IXMLDOMNodeList *create_children_nodelist( xmlNodePtr ); -extern IXMLDOMNamedNodeMap *create_nodemap( xmlNodePtr, const struct nodemap_funcs* ); -extern IUnknown *create_doc_fragment( xmlNodePtr ); -extern IUnknown *create_doc_entity_ref( xmlNodePtr ); -extern IUnknown *create_doc_type( xmlNodePtr ); -extern HRESULT create_selection( xmlNodePtr, xmlChar*, IXMLDOMNodeList** ); -extern HRESULT create_selection_from_nodeset( xmlXPathObjectPtr, IXMLDOMNodeList ** ); -extern HRESULT create_enumvariant( IUnknown*, BOOL, const struct enumvariant_funcs*, IEnumVARIANT**); -extern HRESULT create_dom_implementation(IXMLDOMImplementation **obj); - -/* data accessors */ -xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type ); - -/* helpers */ -extern xmlChar *xmlChar_from_wchar( LPCWSTR str ); - -extern void xmldoc_init( xmlDocPtr doc, MSXML_VERSION version ); -extern LONG xmldoc_add_ref( xmlDocPtr doc ); -extern LONG xmldoc_release( xmlDocPtr doc ); -extern LONG xmldoc_add_refs( xmlDocPtr doc, LONG refs ); -extern LONG xmldoc_release_refs ( xmlDocPtr doc, LONG refs ); -extern void xmlnode_add_ref(xmlNodePtr node); -extern void xmlnode_release(xmlNodePtr node); -extern int xmlnode_get_inst_cnt( xmlnode *node ); -extern HRESULT xmldoc_add_orphan( xmlDocPtr doc, xmlNodePtr node ); -extern HRESULT xmldoc_remove_orphan( xmlDocPtr doc, xmlNodePtr node ); -extern void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node); -extern xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc); -extern MSXML_VERSION xmldoc_version( xmlDocPtr doc ); +extern HRESULT create_domdoc(struct domnode *node, IUnknown **); +extern HRESULT create_node(struct domnode *node, IXMLDOMNode **); +extern HRESULT create_element(struct domnode *, IUnknown **); +extern HRESULT create_attribute(struct domnode *, IUnknown **); +extern HRESULT create_attribute_node(const WCHAR *name, const WCHAR *uri, struct domnode *, IXMLDOMNode **); +extern HRESULT create_text(struct domnode *, IUnknown **); +extern HRESULT create_pi(struct domnode *, IUnknown **); +extern HRESULT create_pi_node(struct domnode *, const WCHAR *, const WCHAR *, IXMLDOMProcessingInstruction **); +extern HRESULT create_comment(struct domnode *, IUnknown **); +extern HRESULT create_cdata(struct domnode *, IUnknown **); +extern HRESULT create_children_nodelist(struct domnode *, IXMLDOMNodeList **); +extern HRESULT create_nodemap(struct domnode *, const struct nodemap_funcs *, IXMLDOMNamedNodeMap **); +extern HRESULT create_doc_fragment(struct domnode *, IUnknown **); +extern HRESULT create_entity_ref(struct domnode *, IUnknown **); +extern HRESULT create_doc_type(struct domnode *, IUnknown **); +extern HRESULT create_selection(struct domnode *, BSTR, bool xpath, IXMLDOMNodeList** ); +extern HRESULT create_selection_from_nodeset( xmlXPathObjectPtr, IXMLDOMNodeList ** ); +extern HRESULT create_enumvariant( IUnknown*, BOOL, const struct enumvariant_funcs*, IEnumVARIANT**); +extern HRESULT create_dom_implementation(IXMLDOMImplementation **obj); extern void wineXmlCallbackLog(char const* caller, xmlErrorLevel lvl, char const* msg, va_list ap); extern void wineXmlCallbackError(char const* caller, const xmlError* err); @@ -208,64 +277,70 @@ extern void wineXmlCallbackError(char const* caller, const xmlError* err); #define LIBXML2_CALLBACK_SERROR(caller, err) wineXmlCallbackError(#caller, err) -extern BOOL is_preserving_whitespace(xmlNodePtr node); -extern BOOL is_xpathmode(const xmlDocPtr doc); -extern void set_xpathmode(xmlDocPtr doc, BOOL xpath); - -extern void init_xmlnode(xmlnode*,xmlNodePtr,IXMLDOMNode*,dispex_static_data_t*); -extern void destroy_xmlnode(xmlnode*); -extern BOOL node_query_interface(xmlnode*,REFIID,void**); -extern xmlnode *get_node_obj(IXMLDOMNode*); - -extern HRESULT node_append_child(xmlnode*,IXMLDOMNode*,IXMLDOMNode**); -extern HRESULT node_get_nodeName(xmlnode*,BSTR*); -extern HRESULT node_get_content(xmlnode*,VARIANT*); -extern HRESULT node_set_content(xmlnode*,LPCWSTR); -extern HRESULT node_put_value(xmlnode*,VARIANT*); -extern HRESULT node_put_value_escaped(xmlnode*,VARIANT*); -extern HRESULT node_get_parent(xmlnode*,IXMLDOMNode**); -extern HRESULT node_get_child_nodes(xmlnode*,IXMLDOMNodeList**); -extern HRESULT node_get_first_child(xmlnode*,IXMLDOMNode**); -extern HRESULT node_get_last_child(xmlnode*,IXMLDOMNode**); -extern HRESULT node_get_previous_sibling(xmlnode*,IXMLDOMNode**); -extern HRESULT node_get_next_sibling(xmlnode*,IXMLDOMNode**); -extern HRESULT node_insert_before(xmlnode*,IXMLDOMNode*,const VARIANT*,IXMLDOMNode**); -extern HRESULT node_replace_child(xmlnode*,IXMLDOMNode*,IXMLDOMNode*,IXMLDOMNode**); -extern HRESULT node_put_text(xmlnode*,BSTR); -extern HRESULT node_get_xml(xmlnode*,BOOL,BSTR*); -extern HRESULT node_clone(xmlnode*,VARIANT_BOOL,IXMLDOMNode**); -extern HRESULT node_get_prefix(xmlnode*,BSTR*); -extern HRESULT node_get_base_name(xmlnode*,BSTR*); -extern HRESULT node_get_namespaceURI(xmlnode*,BSTR*); -extern HRESULT node_remove_child(xmlnode*,IXMLDOMNode*,IXMLDOMNode**); -extern HRESULT node_has_childnodes(const xmlnode*,VARIANT_BOOL*); -extern HRESULT node_get_owner_doc(const xmlnode*,IXMLDOMDocument**); -extern HRESULT node_get_text(const xmlnode*,BSTR*); -extern HRESULT node_select_nodes(const xmlnode*,BSTR,IXMLDOMNodeList**); -extern HRESULT node_select_singlenode(const xmlnode*,BSTR,IXMLDOMNode**); -extern HRESULT node_transform_node(const xmlnode*,IXMLDOMNode*,BSTR*); -extern HRESULT node_transform_node_params(const xmlnode*,IXMLDOMNode*,BSTR*,ISequentialStream*, +extern bool node_query_interface(struct domnode*,REFIID,void**); +extern struct domnode *get_node_obj(void *iface); +extern bool parser_is_valid_qualified_name(const WCHAR *name); +extern HRESULT parse_xml_decl_body(const WCHAR *text, BSTR *version, BSTR *encoding, BSTR *standalone); + +extern HRESULT node_append_child(struct domnode*,IXMLDOMNode*,IXMLDOMNode**); +extern HRESULT node_attribute_get_namespace_uri(struct domnode *, BSTR *); +extern HRESULT node_get_name(struct domnode*,BSTR*); +extern HRESULT node_put_data(struct domnode*, const WCHAR *); +extern HRESULT node_get_data(struct domnode*, BSTR *); +extern XDR_DT node_get_data_type(const struct domnode*); +extern HRESULT node_append_data(struct domnode*, BSTR); +extern HRESULT node_put_value(struct domnode*,VARIANT*); +extern HRESULT node_get_attribute(const struct domnode *,const WCHAR *,IXMLDOMAttribute **); +extern HRESULT node_get_qualified_attribute(const struct domnode *, const WCHAR *name, const WCHAR *uri, IXMLDOMNode **); +extern HRESULT node_get_attribute_by_index(const struct domnode *, LONG, IXMLDOMNode **); +extern HRESULT node_get_attribute_value(struct domnode *,const WCHAR *,VARIANT *); +extern HRESULT node_set_attribute(struct domnode *, IXMLDOMNode *, IXMLDOMNode **); +extern HRESULT node_set_attribute_value(struct domnode *,const WCHAR *,const VARIANT *); +extern HRESULT node_remove_attribute(struct domnode *, const WCHAR *, IXMLDOMNode **); +extern HRESULT node_remove_attribute_node(struct domnode *,IXMLDOMAttribute *,IXMLDOMAttribute **); +extern HRESULT node_remove_qualified_attribute(struct domnode *, const WCHAR *, const WCHAR *, IXMLDOMNode **); +extern HRESULT node_get_parent(struct domnode*,IXMLDOMNode**); +extern HRESULT node_get_child_nodes(struct domnode *,IXMLDOMNodeList**); +extern HRESULT node_get_first_child(struct domnode *,IXMLDOMNode**); +extern HRESULT node_get_last_child(struct domnode *,IXMLDOMNode**); +extern HRESULT node_get_previous_sibling(struct domnode*,IXMLDOMNode**); +extern HRESULT node_get_next_sibling(struct domnode*,IXMLDOMNode**); +extern HRESULT node_insert_before(struct domnode*,IXMLDOMNode*,const VARIANT*,IXMLDOMNode**); +extern HRESULT node_replace_child(struct domnode*,IXMLDOMNode*,IXMLDOMNode*,IXMLDOMNode**); +extern HRESULT node_get_xml(struct domnode *, BSTR*); +extern HRESULT node_clone(struct domnode*,VARIANT_BOOL,IXMLDOMNode**); +extern HRESULT node_get_prefix(struct domnode*,BSTR*); +extern HRESULT node_get_base_name(struct domnode*,BSTR*); +extern HRESULT node_get_namespaceURI(struct domnode*, BSTR *); +extern HRESULT node_remove_child(struct domnode*,IXMLDOMNode*,IXMLDOMNode**); +extern HRESULT node_has_childnodes(const struct domnode*,VARIANT_BOOL*); +extern HRESULT node_get_owner_document(const struct domnode*,IXMLDOMDocument**); +extern HRESULT node_get_text(const struct domnode*,BSTR*); +extern HRESULT node_get_preserved_text(const struct domnode*,BSTR*); +extern HRESULT node_get_value(struct domnode *node, VARIANT *value); +extern HRESULT node_select_nodes(struct domnode*,BSTR,IXMLDOMNodeList**); +extern HRESULT node_select_singlenode(struct domnode *,BSTR,IXMLDOMNode**); +extern HRESULT node_transform_node(struct domnode*,IXMLDOMNode*,BSTR*); +extern HRESULT node_transform_node_params(struct domnode*,IXMLDOMNode*,BSTR*,ISequentialStream*, const struct xslprocessor_params*); extern HRESULT node_create_supporterrorinfo(const tid_t*,void**); +extern HRESULT node_save(struct domnode *, IStream *); +extern HRESULT node_get_elements_by_tagname(struct domnode *,BSTR,IXMLDOMNodeList**); +extern HRESULT node_validate(struct domnode *, IXMLDOMNode *, IXMLDOMParseError **); +extern void node_move_children(struct domnode *dst, struct domnode *src); -extern HRESULT get_domdoc_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document); +extern UINT get_codepage_for_encoding(const WCHAR *encoding); extern HRESULT SchemaCache_validate_tree(IXMLDOMSchemaCollection2*, xmlNodePtr); -extern XDR_DT SchemaCache_get_node_dt(IXMLDOMSchemaCollection2*, xmlNodePtr); -extern HRESULT cache_from_doc_ns(IXMLDOMSchemaCollection2*, xmlnode*); +extern XDR_DT SchemaCache_get_node_dt(IXMLDOMSchemaCollection2 *, const WCHAR *name, const WCHAR *uri); +extern HRESULT cache_from_doc_ns(IXMLDOMSchemaCollection2*, struct domnode *); extern XDR_DT str_to_dt(xmlChar const* str, int len /* calculated if -1 */); extern XDR_DT bstr_to_dt(OLECHAR const* bstr, int len /* calculated if -1 */); extern xmlChar const* dt_to_str(XDR_DT dt); extern const char* debugstr_dt(XDR_DT dt); extern OLECHAR const* dt_to_bstr(XDR_DT dt); -extern HRESULT dt_validate(XDR_DT dt, xmlChar const* content); - -extern BSTR EnsureCorrectEOL(BSTR); - -extern xmlChar* tagName_to_XPath(const BSTR tagName); - -extern HRESULT dom_pi_put_xml_decl(IXMLDOMNode *node, BSTR data); +extern HRESULT dt_validate(XDR_DT dt, const WCHAR *content); #include <libxslt/documents.h> extern xmlDocPtr xslt_doc_default_loader(const xmlChar *uri, xmlDictPtr dict, int options, @@ -343,6 +418,7 @@ static inline HRESULT return_null_var(VARIANT *p) return E_INVALIDARG; V_VT(p) = VT_NULL; + V_UINT_PTR(p) = 0; return S_FALSE; } @@ -378,6 +454,8 @@ extern HRESULT MXNamespaceManager_create(void**); extern HRESULT XMLParser_create(void**); extern HRESULT XMLView_create(void**); +extern HRESULT stream_wrapper_create(const void *, DWORD, ISequentialStream **); + /* Error Codes - not defined anywhere in the public headers */ #define E_XML_ELEMENT_UNDECLARED 0xC00CE00D #define E_XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E @@ -393,7 +471,4 @@ extern HRESULT XMLView_create(void**); /* ... */ #define E_XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020 -#define NODE_PRIV_TRAILING_IGNORABLE_WS 0x40000000 -#define NODE_PRIV_CHILD_IGNORABLE_WS 0x80000000 -#define NODE_PRIV_REFCOUNT_MASK ~(NODE_PRIV_TRAILING_IGNORABLE_WS|NODE_PRIV_CHILD_IGNORABLE_WS) #endif /* __MSXML_PRIVATE__ */ diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c index 0024d375934..6b1cd4706cb 100644 --- a/dlls/msxml3/mxwriter.c +++ b/dlls/msxml3/mxwriter.c @@ -279,6 +279,17 @@ static HRESULT get_code_page(xml_encoding encoding, UINT *cp) return S_OK; } +UINT get_codepage_for_encoding(const WCHAR *encoding) +{ + for (int i = 0; i < ARRAYSIZE(xml_encoding_map); ++i) + { + if (!wcsicmp(encoding, xml_encoding_map[i].encoding)) + return xml_encoding_map[i].cp; + } + + return 0; +} + static HRESULT init_output_buffer(xml_encoding encoding, output_buffer *buffer) { HRESULT hr; diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index 349e154e05c..03dc4a21614 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -21,11 +21,13 @@ #define COBJMACROS #include <stdarg.h> +#include <assert.h> #include <libxml/parser.h> #include <libxml/parserInternals.h> #include <libxml/xmlerror.h> #include <libxml/HTMLtree.h> +#include <libxml/tree.h> #include <libxslt/pattern.h> #include <libxslt/transform.h> #include <libxslt/imports.h> @@ -46,36 +48,96 @@ #include "objsafe.h" #include "msxml_private.h" +#include "saxreader_extensions.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(msxml); -static const IID IID_xmlnode = {0x4f2f4ba2,0xb822,0x11df,{0x8b,0x8a,0x68,0x50,0xdf,0xd7,0x20,0x85}}; +static const IID IID_domnode = {0x4f2f4ba2,0xb822,0x11df,{0x8b,0x8a,0x68,0x50,0xdf,0xd7,0x20,0x85}}; -xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type ) +struct string_buffer { - xmlnode *This; + WCHAR *data; + size_t count; + size_t capacity; - if ( !iface ) - return NULL; - This = get_node_obj( iface ); - if ( !This || !This->node ) - return NULL; - if ( type && This->node->type != type ) - return NULL; - return This->node; + HRESULT _status; + HRESULT *status; +}; + +static void string_buffer_init(struct string_buffer *buffer) +{ + memset(buffer, 0, sizeof(*buffer)); + buffer->status = &buffer->_status; +} + +static void string_append(struct string_buffer *buffer, const WCHAR *str, UINT len) +{ + if (*buffer->status != S_OK) + return; + + if (!array_reserve((void **)&buffer->data, &buffer->capacity, buffer->count + len, sizeof(*str))) + { + *buffer->status = E_OUTOFMEMORY; + free(buffer->data); + return; + } + + memcpy(buffer->data + buffer->count, str, len * sizeof(WCHAR)); + buffer->count += len; +} + +static void string_buffer_cleanup(struct string_buffer *buffer) +{ + free(buffer->data); + buffer->data = NULL; + buffer->count = buffer->capacity = 0; +} + +static HRESULT string_to_bstr_slice(struct string_buffer *buffer, size_t offset, size_t length, BSTR *str) +{ + if (!str) + { + string_buffer_cleanup(buffer); + return E_INVALIDARG; + } + + *str = NULL; + + if (*buffer->status != S_OK) + { + string_buffer_cleanup(buffer); + return *buffer->status; + } + + if ((length && offset >= buffer->count) || length + offset > buffer->count) + { + *buffer->status = E_INVALIDARG; + string_buffer_cleanup(buffer); + return *buffer->status; + } + + *str = SysAllocStringLen(buffer->data + offset, length); + string_buffer_cleanup(buffer); + + return *str ? S_OK : E_OUTOFMEMORY; } -BOOL node_query_interface(xmlnode *This, REFIID riid, void **ppv) +static HRESULT string_to_bstr(struct string_buffer *buffer, BSTR *str) { - if(IsEqualGUID(&IID_xmlnode, riid)) { - TRACE("(%p)->(IID_xmlnode %p)\n", This, ppv); - *ppv = This; - return TRUE; + return string_to_bstr_slice(buffer, 0, buffer->count, str); +} + +bool node_query_interface(struct domnode *node, REFIID riid, void **obj) +{ + if (IsEqualGUID(&IID_domnode, riid)) + { + *obj = node; + return true; } - return dispex_query_interface(&This->dispex, riid, ppv); + return false; } /* common ISupportErrorInfo implementation */ @@ -93,8 +155,7 @@ static inline SupportErrorInfo *impl_from_ISupportErrorInfo(ISupportErrorInfo *i static HRESULT WINAPI SupportErrorInfo_QueryInterface(ISupportErrorInfo *iface, REFIID riid, void **obj) { - SupportErrorInfo *This = impl_from_ISupportErrorInfo(iface); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); *obj = NULL; @@ -133,7 +194,7 @@ static HRESULT WINAPI SupportErrorInfo_InterfaceSupportsErrorInfo(ISupportErrorI SupportErrorInfo *This = impl_from_ISupportErrorInfo(iface); enum tid_t const *tid; - TRACE("(%p)->(%s)\n", This, debugstr_guid(riid)); + TRACE("%p, %s.\n", iface, debugstr_guid(riid)); tid = This->iids; while (*tid != NULL_tid) @@ -169,2658 +230,4356 @@ HRESULT node_create_supporterrorinfo(enum tid_t const *iids, void **obj) return S_OK; } -xmlnode *get_node_obj(IXMLDOMNode *node) +struct domnode *get_node_obj(void *node) { - xmlnode *obj = NULL; - HRESULT hres; + struct domnode *obj = NULL; + HRESULT hr; - hres = IXMLDOMNode_QueryInterface(node, &IID_xmlnode, (void**)&obj); - if (!obj) WARN("node is not our IXMLDOMNode implementation\n"); - return SUCCEEDED(hres) ? obj : NULL; + hr = IUnknown_QueryInterface((IUnknown *)node, &IID_domnode, (void **)&obj); + if (!obj) WARN("Node is not our IXMLDOMNode implementation.\n"); + return SUCCEEDED(hr) ? obj : NULL; } -HRESULT node_get_nodeName(xmlnode *This, BSTR *name) +static struct domnode *node_get_doc(struct domnode *node) { - BSTR prefix, base; - HRESULT hr; - - if (!name) - return E_INVALIDARG; - - hr = node_get_base_name(This, &base); - if (hr != S_OK) return hr; - - if (!base[0] && xmldoc_version(This->node->doc) != MSXML6) - { - SysFreeString(base); - *name = SysAllocString(L"xmlns"); - return S_OK; - } - - hr = node_get_prefix(This, &prefix); - if (hr == S_OK) - { - static const WCHAR colW = ':'; - WCHAR *ptr; - - /* +1 for ':' */ - ptr = *name = SysAllocStringLen(NULL, SysStringLen(base) + SysStringLen(prefix) + 1); - if (SysStringByteLen(prefix)) - { - memcpy(ptr, prefix, SysStringByteLen(prefix)); - ptr += SysStringLen(prefix); - } - if (SysStringByteLen(base)) - { - if (SysStringByteLen(prefix)) - memcpy(ptr++, &colW, sizeof(WCHAR)); - memcpy(ptr, base, SysStringByteLen(base)); - } - - SysFreeString(base); - SysFreeString(prefix); - } - else - *name = base; - - return S_OK; + return node->owner ? node->owner : node; } -HRESULT node_get_content(xmlnode *This, VARIANT *value) +HRESULT node_get_name(struct domnode *node, BSTR *name) { - xmlChar *content; - - if(!value) - return E_INVALIDARG; - - content = xmlNodeGetContent(This->node); - V_VT(value) = VT_BSTR; - V_BSTR(value) = bstr_from_xmlChar( content ); - xmlFree(content); - - TRACE("%p returned %s\n", This, debugstr_w(V_BSTR(value))); - return S_OK; + return return_bstr(node->qname, name); } -HRESULT node_set_content(xmlnode *This, LPCWSTR value) +HRESULT node_append_data(struct domnode *node, BSTR data) { - xmlChar *str; + UINT len, current; + BSTR str; + + if (!(len = SysStringLen(data))) + return S_OK; - TRACE("(%p)->(%s)\n", This, debugstr_w(value)); - str = xmlchar_from_wchar(value); - if(!str) + current = SysStringLen(node->data); + if (!(str = SysAllocStringLen(NULL, current + len))) return E_OUTOFMEMORY; - xmlNodeSetContent(This->node, str); - free(str); + memcpy(str, node->data, current * sizeof(WCHAR)); + memcpy(&str[current], data, len * sizeof(WCHAR)); + str[current + len] = 0; + + SysFreeString(node->data); + node->data = str; + return S_OK; } -static HRESULT node_set_content_escaped(xmlnode *This, LPCWSTR value) +static HRESULT variant_get_str_value(const VARIANT *src, VARIANT *tmp, BSTR *value) { - xmlChar *str, *escaped; + HRESULT hr; - TRACE("(%p)->(%s)\n", This, debugstr_w(value)); - str = xmlchar_from_wchar(value); - if(!str) - return E_OUTOFMEMORY; + VariantInit(tmp); + *value = NULL; - escaped = xmlEncodeSpecialChars(NULL, str); - if(!escaped) + if (V_VT(src) == VT_BSTR) { - free(str); - return E_OUTOFMEMORY; + *value = V_BSTR(src); + return S_OK; } - xmlNodeSetContent(This->node, escaped); - - free(str); - xmlFree(escaped); + hr = VariantChangeType(tmp, src, 0, VT_BSTR); + if (hr != S_OK) + { + WARN("Failed to change to BSTR\n"); + return hr; + } + *value = V_BSTR(tmp); return S_OK; } -HRESULT node_put_value(xmlnode *This, VARIANT *value) +static HRESULT node_put_text_value(struct domnode *node, const VARIANT *value) { HRESULT hr; + VARIANT v; + BSTR str; - if (V_VT(value) != VT_BSTR) - { - VARIANT string_value; - - VariantInit(&string_value); - hr = VariantChangeType(&string_value, value, 0, VT_BSTR); - if(FAILED(hr)) { - WARN("Couldn't convert to VT_BSTR\n"); - return hr; - } + if (FAILED(hr = variant_get_str_value(value, &v, &str))) + return hr; - hr = node_set_content(This, V_BSTR(&string_value)); - VariantClear(&string_value); - } - else - hr = node_set_content(This, V_BSTR(value)); + hr = node_put_data(node, str); + VariantClear(&v); return hr; } -HRESULT node_put_value_escaped(xmlnode *This, VARIANT *value) +HRESULT node_put_value(struct domnode *node, VARIANT *value) { HRESULT hr; - if (V_VT(value) != VT_BSTR) + switch (node->type) { - VARIANT string_value; - - VariantInit(&string_value); - hr = VariantChangeType(&string_value, value, 0, VT_BSTR); - if(FAILED(hr)) { - WARN("Couldn't convert to VT_BSTR\n"); - return hr; - } - - hr = node_set_content_escaped(This, V_BSTR(&string_value)); - VariantClear(&string_value); + case NODE_TEXT: + case NODE_COMMENT: + case NODE_PROCESSING_INSTRUCTION: + case NODE_CDATA_SECTION: + case NODE_ATTRIBUTE: + hr = node_put_text_value(node, value); + break; + default: + FIXME("Unimplemented type %d.\n", node->type); + hr = E_NOTIMPL; } - else - hr = node_set_content_escaped(This, V_BSTR(value)); return hr; } -static HRESULT get_node( - xmlnode *This, - const char *name, - xmlNodePtr node, - IXMLDOMNode **out ) +static HRESULT get_node(struct domnode *node, IXMLDOMNode **out) { - TRACE("(%p)->(%s %p %p)\n", This, name, node, out ); - - if ( !out ) + if (!out) return E_INVALIDARG; - /* if we don't have a doc, use our parent. */ - if(node && !node->doc && node->parent) - node->doc = node->parent->doc; - - *out = create_node( node ); - if (!*out) - return S_FALSE; - return S_OK; + return create_node(node, out); } -HRESULT node_get_parent(xmlnode *This, IXMLDOMNode **parent) +HRESULT node_get_parent(struct domnode *node, IXMLDOMNode **ret) { - return get_node( This, "parent", This->node->parent, parent ); + return get_node(node->parent, ret); } -HRESULT node_get_child_nodes(xmlnode *This, IXMLDOMNodeList **ret) +HRESULT node_get_child_nodes(struct domnode *node, IXMLDOMNodeList **ret) { if(!ret) return E_INVALIDARG; - *ret = create_children_nodelist(This->node); - if(!*ret) - return E_OUTOFMEMORY; - - return S_OK; + return create_children_nodelist(node, ret); } -HRESULT node_get_first_child(xmlnode *This, IXMLDOMNode **ret) +static struct domnode *node_from_entry(struct list *entry) { - return get_node(This, "firstChild", This->node->children, ret); + return entry ? LIST_ENTRY(entry, struct domnode, entry) : NULL; } -HRESULT node_get_last_child(xmlnode *This, IXMLDOMNode **ret) +struct domnode *domnode_get_first_child(struct domnode *node) { - return get_node(This, "lastChild", This->node->last, ret); + return node_from_entry(list_head(&node->children)); } -HRESULT node_get_previous_sibling(xmlnode *This, IXMLDOMNode **ret) +static struct domnode *domnode_get_previous_sibling(struct domnode *node) { - return get_node(This, "previous", This->node->prev, ret); + if (node->parent) + return node_from_entry(list_prev(&node->parent->children, &node->entry)); + + return NULL; } -HRESULT node_get_next_sibling(xmlnode *This, IXMLDOMNode **ret) +HRESULT node_get_first_child(struct domnode *node, IXMLDOMNode **ret) { - return get_node(This, "next", This->node->next, ret); + return get_node(domnode_get_first_child(node), ret); } -static int node_get_inst_cnt(xmlNodePtr node) +HRESULT node_get_last_child(struct domnode *node, IXMLDOMNode **ret) { - int ret = *(LONG *)&node->_private & NODE_PRIV_REFCOUNT_MASK; - xmlNodePtr child; - - /* add attribute counts */ - if (node->type == XML_ELEMENT_NODE) - { - xmlAttrPtr prop = node->properties; - - while (prop) - { - ret += node_get_inst_cnt((xmlNodePtr)prop); - prop = prop->next; - } - } - - /* add children counts */ - child = node->children; - while (child) - { - ret += node_get_inst_cnt(child); - child = child->next; - } - - return ret; + return get_node(node_from_entry(list_tail(&node->children)), ret); } -int xmlnode_get_inst_cnt(xmlnode *node) +HRESULT node_get_previous_sibling(struct domnode *node, IXMLDOMNode **ret) { - return node_get_inst_cnt(node->node); + struct domnode *sibling = NULL; + + if (node->parent) + sibling = node_from_entry(list_prev(&node->parent->children, &node->entry)); + return get_node(sibling, ret); } -/* _private field holds a number of COM instances spawned from this libxml2 node - * most significant bits are used to store information about ignorable whitespace nodes */ -void xmlnode_add_ref(xmlNodePtr node) +struct domnode *domnode_get_next_sibling(struct domnode *node) { - if (node->type == XML_DOCUMENT_NODE) return; - InterlockedIncrement((LONG*)&node->_private); + if (node->parent) + return node_from_entry(list_next(&node->parent->children, &node->entry)); + + return NULL; } -void xmlnode_release(xmlNodePtr node) +HRESULT node_get_next_sibling(struct domnode *node, IXMLDOMNode **ret) { - if (node->type == XML_DOCUMENT_NODE) return; - InterlockedDecrement((LONG*)&node->_private); + return get_node(domnode_get_next_sibling(node), ret); } -HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT *ref_child, - IXMLDOMNode **ret) +static bool domnode_is_valid_child_type(const struct domnode *node, struct domnode *child) { - IXMLDOMNode *before = NULL; - xmlnode *node_obj; - int refcount = 0; - xmlDocPtr doc; - HRESULT hr; - - if(!new_child) - return E_INVALIDARG; + struct domnode *n; - node_obj = get_node_obj(new_child); - if(!node_obj) return E_FAIL; - - switch(V_VT(ref_child)) + if (!(node->type == NODE_DOCUMENT + || node->type == NODE_DOCUMENT_FRAGMENT + || node->type == NODE_ELEMENT + || node->type == NODE_ATTRIBUTE)) { - case VT_EMPTY: - case VT_NULL: - break; + return false; + } - case VT_UNKNOWN: - case VT_DISPATCH: - if (V_UNKNOWN(ref_child)) + if (child->type == NODE_DOCUMENT_FRAGMENT) + { + LIST_FOR_EACH_ENTRY(n, &child->children, struct domnode, entry) { - hr = IUnknown_QueryInterface(V_UNKNOWN(ref_child), &IID_IXMLDOMNode, (void**)&before); - if(FAILED(hr)) return hr; + if (!domnode_is_valid_child_type(node, n)) return false; } - break; - default: - FIXME("refChild var type %x\n", V_VT(ref_child)); - return E_FAIL; + return true; } - TRACE("new child %p, This->node %p\n", node_obj->node, This->node); + switch (node->type) + { + case NODE_DOCUMENT: + if (child->type == NODE_ELEMENT) + { + /* Document is allowed a single element child. */ + + LIST_FOR_EACH_ENTRY(n, &node->children, struct domnode, entry) + { + if (n->type == NODE_ELEMENT) + return false; + } + + return true; + } - if(!node_obj->node->parent) - if(xmldoc_remove_orphan(node_obj->node->doc, node_obj->node) != S_OK) - WARN("%p is not an orphan of %p\n", node_obj->node, node_obj->node->doc); + return (child->type == NODE_COMMENT + || child->type == NODE_PROCESSING_INSTRUCTION); - refcount = xmlnode_get_inst_cnt(node_obj); + case NODE_DOCUMENT_FRAGMENT: + case NODE_ELEMENT: + return (child->type == NODE_TEXT + || child->type == NODE_COMMENT + || child->type == NODE_ELEMENT + || child->type == NODE_CDATA_SECTION + || child->type == NODE_ENTITY_REFERENCE + || child->type == NODE_PROCESSING_INSTRUCTION); - if(before) - { - xmlnode *before_node_obj = get_node_obj(before); - IXMLDOMNode_Release(before); - if(!before_node_obj) return E_FAIL; - } + case NODE_ATTRIBUTE: + return (child->type == NODE_TEXT + || child->type == NODE_ENTITY_REFERENCE); - /* unlink from current parent first */ - if(node_obj->parent) - { - hr = IXMLDOMNode_removeChild(node_obj->parent, node_obj->iface, NULL); - if (hr == S_OK) xmldoc_remove_orphan(node_obj->node->doc, node_obj->node); + default: + return false; } - doc = node_obj->node->doc; +} - if(before) - { - xmlNodePtr new_node; - xmlnode *before_node_obj = get_node_obj(before); +/* Link to a new owner, transferring outstanding references. */ +static void domnode_set_owner(struct domnode *node, struct domnode *owner) +{ + struct domnode *n, *old_owner; - /* refs count including subtree */ - if (doc != before_node_obj->node->doc) - refcount = xmlnode_get_inst_cnt(node_obj); + /* Document node does not have the owner set. */ + owner = owner->owner ? owner->owner : owner; - if (refcount) xmldoc_add_refs(before_node_obj->node->doc, refcount); - new_node = xmlAddPrevSibling(before_node_obj->node, node_obj->node); - if (new_node != node_obj->node) - { - if (refcount != 1) - FIXME("referenced xmlNode was freed, expect crashes\n"); - xmlnode_add_ref(new_node); - node_obj->node = new_node; - } - if (refcount) xmldoc_release_refs(doc, refcount); - node_obj->parent = This->parent; - } - else - { - xmlNodePtr new_node; + assert(!!owner); + + old_owner = node->owner; + if (old_owner == owner) + return; - if (doc != This->node->doc) - refcount = xmlnode_get_inst_cnt(node_obj); + list_remove(&node->owner_entry); + node->owner = owner; + owner->refcount += node->refcount; + list_add_tail(&owner->owned, &node->owner_entry); - if (refcount) xmldoc_add_refs(This->node->doc, refcount); - /* xmlAddChild doesn't unlink node from previous parent */ - xmlUnlinkNode(node_obj->node); - new_node = xmlAddChild(This->node, node_obj->node); - if (new_node != node_obj->node) - { - if (refcount != 1) - FIXME("referenced xmlNode was freed, expect crashes\n"); - xmlnode_add_ref(new_node); - node_obj->node = new_node; - } - if (refcount) xmldoc_release_refs(doc, refcount); - node_obj->parent = This->iface; + LIST_FOR_EACH_ENTRY(n, &node->children, struct domnode, entry) + { + domnode_set_owner(n, owner); } - if(ret) + LIST_FOR_EACH_ENTRY(n, &node->attributes, struct domnode, entry) { - IXMLDOMNode_AddRef(new_child); - *ret = new_child; + domnode_set_owner(n, owner); } - TRACE("ret S_OK\n"); - return S_OK; + old_owner->refcount -= node->refcount; + if (old_owner->refcount == 0) + domnode_destroy_tree(old_owner); } -HRESULT node_replace_child(xmlnode *This, IXMLDOMNode *newChild, IXMLDOMNode *oldChild, - IXMLDOMNode **ret) +static void domnode_unlink_child(struct domnode *child) { - xmlnode *old_child, *new_child; - xmlDocPtr leaving_doc; - xmlNode *my_ancestor; - int refcount = 0; + struct domnode *node, *top; - /* Do not believe any documentation telling that newChild == NULL - means removal. It does certainly *not* apply to msxml3! */ - if(!newChild || !oldChild) - return E_INVALIDARG; + if (!child->parent) + return; - if(ret) - *ret = NULL; + /* TODO: should fail to remove doctype child */ + + /* Drop references for the parent and up */ + node = child->parent; + while (node) + { + top = node; + node->refcount -= child->refcount; + node = node->parent; + } - old_child = get_node_obj(oldChild); - if(!old_child) return E_FAIL; + list_remove(&child->entry); + child->parent = NULL; + + if (top->refcount == 0) + domnode_destroy_tree(top); +} + +static void domnode_add_refs(struct domnode *node, unsigned int count) +{ + struct domnode *p = node; - if(old_child->node->parent != This->node) + if (node->owner) + node->owner->refcount += count; + while (p) { - WARN("childNode %p is not a child of %p\n", oldChild, This); - return E_INVALIDARG; + p->refcount += count; + p = p->parent; } +} - new_child = get_node_obj(newChild); - if(!new_child) return E_FAIL; +static void domnode_insert_domnode(struct domnode *node, struct domnode *child, struct domnode *ref_child) +{ + struct domnode *n, *next; - my_ancestor = This->node; - while(my_ancestor) + if (child->type == NODE_DOCUMENT_FRAGMENT) { - if(my_ancestor == new_child->node) + LIST_FOR_EACH_ENTRY_SAFE(n, next, &child->children, struct domnode, entry) { - WARN("tried to create loop\n"); - return E_FAIL; + domnode_insert_domnode(node, n, ref_child); } - my_ancestor = my_ancestor->parent; + + return; } - if(!new_child->node->parent) - if(xmldoc_remove_orphan(new_child->node->doc, new_child->node) != S_OK) - WARN("%p is not an orphan of %p\n", new_child->node, new_child->node->doc); + domnode_unlink_child(child); - leaving_doc = new_child->node->doc; + if (ref_child) + list_add_before(&ref_child->entry, &child->entry); + else + list_add_tail(&node->children, &child->entry); - if (leaving_doc != old_child->node->doc) - refcount = xmlnode_get_inst_cnt(new_child); + child->parent = node; + domnode_add_refs(child->parent, child->refcount); + domnode_set_owner(child, node); +} - if (refcount) xmldoc_add_refs(old_child->node->doc, refcount); - xmlReplaceNode(old_child->node, new_child->node); - if (refcount) xmldoc_release_refs(leaving_doc, refcount); - new_child->parent = old_child->parent; - old_child->parent = NULL; +HRESULT node_insert_before(struct domnode *node, IXMLDOMNode *new_child, const VARIANT *ref_child, + IXMLDOMNode **ret) +{ + struct domnode *child_node, *ref_node = NULL; - xmldoc_add_orphan(old_child->node->doc, old_child->node); + if (!new_child) + return E_INVALIDARG; - if(ret) - { - IXMLDOMNode_AddRef(oldChild); - *ret = oldChild; - } + if (ret) + *ret = NULL; - return S_OK; -} + if (!(child_node = get_node_obj(new_child))) + return E_FAIL; -HRESULT node_remove_child(xmlnode *This, IXMLDOMNode* child, IXMLDOMNode** oldChild) -{ - xmlnode *child_node; + switch (V_VT(ref_child)) + { + case VT_EMPTY: + case VT_NULL: + break; - if(!child) return E_INVALIDARG; + case VT_UNKNOWN: + case VT_DISPATCH: + if (!V_UNKNOWN(ref_child)) + break; - if(oldChild) - *oldChild = NULL; + if (!(ref_node = get_node_obj(V_UNKNOWN(ref_child)))) + return E_FAIL; + if (ref_node->parent != node) + { + WARN("Reference node is not a child of this node.\n"); + return E_FAIL; + } + break; - child_node = get_node_obj(child); - if(!child_node) return E_FAIL; + default: + FIXME("Unexpected reference node type %s.\n", debugstr_variant(ref_child)); + return E_FAIL; + } - if(child_node->node->parent != This->node) + if (!domnode_is_valid_child_type(node, child_node)) { - WARN("childNode %p is not a child of %p\n", child, This); - return E_INVALIDARG; + WARN("Can't add node %p as a child for %p.\n", child_node, node); + return E_FAIL; } - xmlUnlinkNode(child_node->node); - child_node->parent = NULL; - xmldoc_add_orphan(child_node->node->doc, child_node->node); + domnode_insert_domnode(node, child_node, ref_node); - if(oldChild) + if (ret) { - IXMLDOMNode_AddRef(child); - *oldChild = child; + *ret = new_child; + IXMLDOMNode_AddRef(*ret); } return S_OK; } -HRESULT node_append_child(xmlnode *This, IXMLDOMNode *child, IXMLDOMNode **outChild) +HRESULT node_replace_child(struct domnode *node, IXMLDOMNode *newChild, IXMLDOMNode *oldChild, + IXMLDOMNode **ret) { - DOMNodeType type; - VARIANT var; + struct domnode *old_child, *new_child, *curr; + VARIANT ref; HRESULT hr; - if (!child) + if (!newChild || !oldChild) return E_INVALIDARG; - hr = IXMLDOMNode_get_nodeType(child, &type); - if(FAILED(hr) || type == NODE_ATTRIBUTE) { - if (outChild) *outChild = NULL; + if (ret) + *ret = NULL; + + if (!(new_child = get_node_obj(newChild))) return E_FAIL; + + if (!(old_child = get_node_obj(oldChild))) + return E_FAIL; + + if (old_child->parent != node) + { + WARN("Node %p is not a child of %p.\n", old_child, node); + return E_INVALIDARG; } - VariantInit(&var); - return IXMLDOMNode_insertBefore(This->iface, child, var, outChild); + curr = node; + while (curr) + { + if (curr == new_child) + { + WARN("Attempt to create a cycle.\n"); + return E_FAIL; + } + curr = curr->parent; + } + + V_VT(&ref) = VT_DISPATCH; + V_DISPATCH(&ref) = (IDispatch *)oldChild; + if (FAILED(hr = node_insert_before(node, newChild, &ref, NULL))) + return hr; + + return node_remove_child(node, oldChild, ret); } -HRESULT node_has_childnodes(const xmlnode *This, VARIANT_BOOL *ret) +static void domnode_unlink_children(struct domnode *node) { - if (!ret) return E_INVALIDARG; + struct domnode *child, *next; - if (!This->node->children) + LIST_FOR_EACH_ENTRY_SAFE(child, next, &node->children, struct domnode, entry) { - *ret = VARIANT_FALSE; - return S_FALSE; + domnode_unlink_child(child); } - - *ret = VARIANT_TRUE; - return S_OK; } -HRESULT node_get_owner_doc(const xmlnode *This, IXMLDOMDocument **doc) +static void domnode_append_child(struct domnode *parent, struct domnode *node) { - if(!doc) - return E_INVALIDARG; - return get_domdoc_from_xmldoc(This->node->doc, (IXMLDOMDocument3**)doc); + domnode_unlink_child(node); + + list_add_tail(&parent->children, &node->entry); + node->parent = parent; + domnode_add_refs(node->parent, node->refcount); + domnode_set_owner(node, parent); } -HRESULT node_clone(xmlnode *This, VARIANT_BOOL deep, IXMLDOMNode **cloneNode) +HRESULT node_put_data(struct domnode *node, const WCHAR *data) { - IXMLDOMNode *node; - xmlNodePtr clone; + struct string_buffer buffer; + const WCHAR *p = data; + struct domnode *child; + + if (node->flags & DOMNODE_READONLY_VALUE) + return E_FAIL; - if(!cloneNode) return E_INVALIDARG; + /* Markup is checked and rejected. */ - clone = xmlCopyNode(This->node, deep ? 1 : 2); - if (clone) - { - xmlSetTreeDoc(clone, This->node->doc); - xmldoc_add_orphan(clone->doc, clone); + if (node->type == NODE_COMMENT && data && wcsstr(data, L"-->")) + return E_INVALIDARG; + + if (node->type == NODE_PROCESSING_INSTRUCTION && data && wcsstr(data, L"?>")) + return E_INVALIDARG; + + string_buffer_init(&buffer); - node = create_node(clone); - if (!node) + while (p && *p) + { + if (*p == '\r') { - ERR("Copy failed\n"); - xmldoc_remove_orphan(clone->doc, clone); - xmlFreeNode(clone); - return E_FAIL; + if (p[1] == '\n') ++p; + string_append(&buffer, L"\n", 1); } - - *cloneNode = node; + else + { + string_append(&buffer, p, 1); + } + ++p; } - else + + switch (node->type) { - ERR("Copy failed\n"); - return E_FAIL; - } + case NODE_ATTRIBUTE: + case NODE_ELEMENT: + domnode_unlink_children(node); - return S_OK; + /* TODO: error handling */ + domnode_create(NODE_TEXT, NULL, 0, NULL, 0, node->owner, &child); + domnode_append_child(node, child); + + return string_to_bstr(&buffer, &child->data); + + default: + SysFreeString(node->data); + return string_to_bstr(&buffer, &node->data); + } } -static xmlChar* do_get_text(xmlNodePtr node, BOOL trim, DWORD *first, DWORD *last, BOOL *trail_ig_ws) +struct node_dump_ns { - xmlNodePtr child; - xmlChar* str; - BOOL preserving = is_preserving_whitespace(node); - - *first = -1; - *last = 0; + struct list entry; + BSTR prefix; + BSTR uri; + bool own_uri; + int depth; +}; - if (!node->children) +struct node_dump_context +{ + struct string_buffer buffer; + struct { - str = xmlNodeGetContent(node); - *trail_ig_ws = *(DWORD*)&node->_private & NODE_PRIV_CHILD_IGNORABLE_WS; + char *data; + size_t capacity; + } scratch; + + struct list namespaces; + int depth; + + unsigned int indent; + bool needs_formatting; + + bool only_utf16_encoding_decl; + + IStream *stream; + UINT codepage; + HRESULT status; +}; + +static void node_dump_push_namespace(struct node_dump_context *context, BSTR prefix, BSTR uri, bool own_uri) +{ + struct node_dump_ns *ns; + + if (context->status != S_OK) + return; + + if (!(ns = calloc(1, sizeof(*ns)))) + { + context->status = E_OUTOFMEMORY; + return; } - else + + ns->depth = context->depth; + ns->prefix = prefix; + ns->uri = uri; + ns->own_uri = own_uri; + + list_add_tail(&context->namespaces, &ns->entry); +} + +static void node_dump_pop_namespaces(struct node_dump_context *context) +{ + struct node_dump_ns *ns, *next; + + LIST_FOR_EACH_ENTRY_SAFE_REV(ns, next, &context->namespaces, struct node_dump_ns, entry) { - BOOL ig_ws = FALSE; - xmlChar* tmp; - DWORD pos = 0; - str = xmlStrdup(BAD_CAST ""); + if (ns->depth != context->depth) + break; - if (node->type != XML_DOCUMENT_NODE) - ig_ws = *(DWORD*)&node->_private & NODE_PRIV_CHILD_IGNORABLE_WS; - *trail_ig_ws = FALSE; + list_remove(&ns->entry); + if (ns->own_uri) + SysFreeString(ns->uri); + free(ns); + } +} - for (child = node->children; child != NULL; child = child->next) - { - switch (child->type) - { - case XML_ELEMENT_NODE: { - DWORD node_first, node_last; +static void node_dump(struct domnode *node, struct node_dump_context *context); - tmp = do_get_text(child, FALSE, &node_first, &node_last, trail_ig_ws); +static void node_dump_append(struct node_dump_context *context, const WCHAR *text, unsigned int length) +{ + ULONG written, required; - if (node_first!=-1 && pos+node_first<*first) - *first = pos+node_first; - if (node_last && pos+node_last>*last) - *last = pos+node_last; - break; - } - case XML_TEXT_NODE: - tmp = xmlNodeGetContent(child); - if (!preserving && tmp[0]) - { - xmlChar *beg; + if (context->status != S_OK) + return; - for (beg = tmp; *beg; beg++) - if (!isspace(*beg)) break; + if (context->stream) + { + if (context->codepage == ~0u) + { + context->status = IStream_Write(context->stream, text, length * sizeof(WCHAR), &written); + } + else + { + /* NOTE: might be useful to buffer */ - if (!*beg) - { - ig_ws = TRUE; - xmlFree(tmp); - tmp = NULL; - } - } - break; - case XML_CDATA_SECTION_NODE: - case XML_ENTITY_REF_NODE: - case XML_ENTITY_NODE: - tmp = xmlNodeGetContent(child); - break; - default: - tmp = NULL; - break; - } + required = WideCharToMultiByte(context->codepage, 0, text, length, NULL, 0, NULL, NULL); - if ((tmp && *tmp) || child->type==XML_CDATA_SECTION_NODE) + if (!array_reserve((void **)&context->scratch.data, &context->scratch.capacity, + required, sizeof(*context->scratch.data))) { - if (ig_ws && str[0]) - { - str = xmlStrcat(str, BAD_CAST " "); - pos++; - } - if (tmp && *tmp) str = xmlStrcat(str, tmp); - if (child->type==XML_CDATA_SECTION_NODE && pos<*first) - *first = pos; - if (tmp && *tmp) pos += xmlStrlen(tmp); - if (child->type==XML_CDATA_SECTION_NODE && pos>*last) - *last = pos; - ig_ws = FALSE; + context->status = E_OUTOFMEMORY; + return; } - if (tmp) xmlFree(tmp); - if (!ig_ws) - { - ig_ws = *(DWORD*)&child->_private & NODE_PRIV_TRAILING_IGNORABLE_WS; - } - if (!ig_ws) - ig_ws = *trail_ig_ws; - *trail_ig_ws = FALSE; + WideCharToMultiByte(context->codepage, 0, text, length, context->scratch.data, required, NULL, NULL); + context->status = IStream_Write(context->stream, context->scratch.data, required, &written); } - - *trail_ig_ws = ig_ws; } - - switch (node->type) + else { - case XML_ELEMENT_NODE: - case XML_TEXT_NODE: - case XML_ENTITY_REF_NODE: - case XML_ENTITY_NODE: - case XML_DOCUMENT_NODE: - case XML_DOCUMENT_FRAG_NODE: - if (trim && !preserving) - { - xmlChar* ret; - int len; + string_append(&context->buffer, text, length); + } +} - if (!str) - break; +static HRESULT node_get_pi_data(const struct domnode *node, BSTR *p) +{ + struct node_dump_context context = { 0 }; + bool separate = false; + struct domnode *attr; - for (ret = str; *ret && isspace(*ret) && (*first)--; ret++) - if (*last) (*last)--; - for (len = xmlStrlen(ret)-1; len >= 0 && len >= *last; len--) - if(!isspace(ret[len])) break; + if (!wcscmp(node->name, L"xml")) + { + string_buffer_init(&context.buffer); - ret = xmlStrndup(ret, len+1); - xmlFree(str); - str = ret; - break; + LIST_FOR_EACH_ENTRY(attr, &node->attributes, struct domnode, entry) + { + if (separate) + node_dump_append(&context, L" ", 1); + node_dump(attr, &context); + separate = true; } - break; - default: - break; + return string_to_bstr(&context.buffer, p); + } + else + { + return return_bstr(node->data ? node->data : L"", p); } +} - return str; +HRESULT node_get_data(struct domnode *node, BSTR *p) +{ + switch (node->type) + { + case NODE_TEXT: + case NODE_COMMENT: + case NODE_CDATA_SECTION: + return return_bstr(node->data ? node->data : L"", p); + case NODE_PROCESSING_INSTRUCTION: + return node_get_pi_data(node, p); + default: + FIXME("Unhandled type %d.\n", node->type); + return E_NOTIMPL; + } } -HRESULT node_get_text(const xmlnode *This, BSTR *text) +HRESULT node_remove_child(struct domnode *node, IXMLDOMNode *child, IXMLDOMNode **oldChild) { - BSTR str = NULL; - xmlChar *content; - DWORD first, last; - BOOL tmp; + struct domnode *child_node; + + if (!child) + return E_INVALIDARG; + + if (oldChild) + *oldChild = NULL; + + child_node = get_node_obj(child); + if (!child_node) + return E_FAIL; + + if (child_node->parent != node) + { + WARN("Node %p is not a child of %p.\n", child, node); + return E_INVALIDARG; + } - if (!text) return E_INVALIDARG; + if (child_node->type == NODE_DOCUMENT_TYPE) + { + WARN("Can't remove doctype child.\n"); + return E_FAIL; + } + + domnode_unlink_child(child_node); - content = do_get_text(This->node, TRUE, &first, &last, &tmp); - if (content) + if (oldChild) { - str = bstr_from_xmlChar(content); - xmlFree(content); + IXMLDOMNode_AddRef(child); + *oldChild = child; } - /* Always return a string. */ - if (!str) str = SysAllocStringLen( NULL, 0 ); + /* Child node is never freed here, we'll always have outstanding references at this point. */ - TRACE("%p %s\n", This, debugstr_w(str) ); - *text = str; - return S_OK; } -HRESULT node_put_text(xmlnode *This, BSTR text) +static void domnode_unlink_attribute(struct domnode *attr) { - xmlChar *str, *str2; + struct domnode *node, *top; - TRACE("(%p)->(%s)\n", This, debugstr_w(text)); - - str = xmlchar_from_wchar(text); + if (!attr->parent) + return; - /* Escape the string. */ - str2 = xmlEncodeEntitiesReentrant(This->node->doc, str); - free(str); + /* Drop references for the parent and up */ + node = attr->parent; + while (node) + { + top = node; + node->refcount -= attr->refcount; + node = node->parent; + } - xmlNodeSetContent(This->node, str2); - xmlFree(str2); + list_remove(&attr->entry); + attr->parent = NULL; - return S_OK; + if (top->refcount == 0) + domnode_destroy_tree(top); } -BSTR EnsureCorrectEOL(BSTR sInput) +HRESULT node_remove_attribute_node(struct domnode *node, IXMLDOMAttribute *attr, IXMLDOMAttribute **old_attr) { - int nNum = 0; - BSTR sNew; - int nLen; - int i; + struct domnode *attr_node; + + if (!attr) + return E_INVALIDARG; + + if (old_attr) + *old_attr = NULL; + + attr_node = get_node_obj(attr); + if (!attr_node) + return E_FAIL; - nLen = SysStringLen(sInput); - /* Count line endings */ - for(i=0; i < nLen; i++) + if (attr_node->parent != node) { - if(sInput[i] == '\n') - nNum++; + WARN("Node %p is not an attribute of %p.\n", attr, node); + return E_INVALIDARG; } - TRACE("len=%d, num=%d\n", nLen, nNum); + domnode_unlink_attribute(attr_node); - /* Add linefeed as needed */ - if(nNum > 0) + if (old_attr) { - int nPlace = 0; - sNew = SysAllocStringLen(NULL, nLen + nNum); - for(i=0; i < nLen; i++) - { - if(sInput[i] == '\n') - { - sNew[i+nPlace] = '\r'; - nPlace++; - } - sNew[i+nPlace] = sInput[i]; - } - - SysFreeString(sInput); + IXMLDOMAttribute_AddRef(attr); + *old_attr = attr; } - else + + /* Attribute node is never freed here, we'll always have outstanding references at this point. */ + + return S_OK; +} + +HRESULT domnode_get_attribute(const struct domnode *node, const WCHAR *name, struct domnode **attr) +{ + struct domnode *n; + + /* TODO: return E_FAIL for invalid XML names */ + + LIST_FOR_EACH_ENTRY(n, &node->attributes, struct domnode, entry) { - sNew = sInput; + if (!wcscmp(n->qname, name)) + { + *attr = n; + return S_OK; + } } - TRACE("len %d\n", SysStringLen(sNew)); + *attr = NULL; + return S_FALSE; +} + +static bool is_same_uri(const struct domnode *node, const WCHAR *uri) +{ + if (node->uri) + return uri && !wcscmp(node->uri, uri); - return sNew; + return !uri; } -/* - * We are trying to replicate the same behaviour as msxml by converting - * line endings to \r\n and using indents as \t. The problem is that msxml - * only formats nodes that have a line ending. Using libxml we cannot - * reproduce behaviour exactly. - * - */ -HRESULT node_get_xml(xmlnode *This, BOOL ensure_eol, BSTR *ret) +static HRESULT domnode_get_qualified_attribute(const struct domnode *node, const WCHAR *name, + const WCHAR *uri, struct domnode **attr) { - xmlBufferPtr xml_buf; - xmlNodePtr xmldecl; - int size; + struct domnode *n; - if(!ret) - return E_INVALIDARG; + LIST_FOR_EACH_ENTRY(n, &node->attributes, struct domnode, entry) + { + if (!wcscmp(n->name, name) && is_same_uri(n, uri)) + { + *attr = n; + return S_OK; + } + } - *ret = NULL; + *attr = NULL; + return S_FALSE; +} - xml_buf = xmlBufferCreate(); - if(!xml_buf) - return E_OUTOFMEMORY; +HRESULT node_remove_attribute(struct domnode *node, const WCHAR *name, IXMLDOMNode **ret) +{ + struct domnode *attr; + HRESULT hr; - xmldecl = xmldoc_unlink_xmldecl( This->node->doc ); + if (!name) + return E_INVALIDARG; - size = xmlNodeDump(xml_buf, This->node->doc, This->node, 0, 1); - if(size > 0) { - const xmlChar *buf_content; - BSTR content; + if (ret) + *ret = NULL; - /* Attribute Nodes return a space in front of their name */ - buf_content = xmlBufferContent(xml_buf); + if ((hr = domnode_get_attribute(node, name, &attr)) != S_OK) + return hr; - content = bstr_from_xmlChar(buf_content + (buf_content[0] == ' ' ? 1 : 0)); - if(ensure_eol) - content = EnsureCorrectEOL(content); + if (ret) + hr = create_node(attr, ret); - *ret = content; - }else { - *ret = SysAllocStringLen(NULL, 0); - } + if (SUCCEEDED(hr)) + domnode_unlink_attribute(attr); - xmlBufferFree(xml_buf); - xmldoc_link_xmldecl( This->node->doc, xmldecl ); - return *ret ? S_OK : E_OUTOFMEMORY; + return hr; } -/* duplicates xmlBufferWriteQuotedString() logic */ -static void xml_write_quotedstring(xmlOutputBufferPtr buf, const xmlChar *string) +HRESULT domnode_create(DOMNodeType type, const WCHAR *name, int name_len, const WCHAR *uri, int uri_len, + struct domnode *owner, struct domnode **node) { - const xmlChar *cur, *base; + struct domnode *object; + WCHAR *p; + BSTR str; - if (xmlStrchr(string, '\"')) + *node = NULL; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + str = SysAllocStringLen(name, name_len); + if (type == NODE_ELEMENT || type == NODE_ATTRIBUTE) { - if (xmlStrchr(string, '\'')) + if (!parser_is_valid_qualified_name(str)) { - xmlOutputBufferWrite(buf, 1, "\""); - base = cur = string; + SysFreeString(str); + return E_FAIL; + } - while (*cur) - { - if (*cur == '"') - { - if (base != cur) - xmlOutputBufferWrite(buf, cur-base, (const char*)base); - xmlOutputBufferWrite(buf, 6, """); - cur++; - base = cur; - } - else - cur++; - } - if (base != cur) - xmlOutputBufferWrite(buf, cur-base, (const char*)base); - xmlOutputBufferWrite(buf, 1, "\""); + if ((p = wcschr(str, ':'))) + { + object->prefix = SysAllocStringLen(str, p - str); + object->name = SysAllocString(p + 1); } else { - xmlOutputBufferWrite(buf, 1, "\'"); - xmlOutputBufferWriteString(buf, (const char*)string); - xmlOutputBufferWrite(buf, 1, "\'"); + object->name = str; } } else { - xmlOutputBufferWrite(buf, 1, "\""); - xmlOutputBufferWriteString(buf, (const char*)string); - xmlOutputBufferWrite(buf, 1, "\""); + object->name = str; } -} + object->qname = str; -static int XMLCALL transform_to_stream_write(void *context, const char *buffer, int len) -{ - DWORD written; - HRESULT hr = ISequentialStream_Write((ISequentialStream *)context, buffer, len, &written); - return hr == S_OK ? written : -1; -} - -/* Output for method "text" */ -static void transform_write_text(xmlDocPtr result, xsltStylesheetPtr style, xmlOutputBufferPtr output) -{ - xmlNodePtr cur = result->children; - while (cur) + if (uri_len) { - if (cur->type == XML_TEXT_NODE) - xmlOutputBufferWriteString(output, (const char*)cur->content); - - /* skip to next node */ - if (cur->children) + if (!(object->uri = SysAllocStringLen(uri, uri_len))) { - if ((cur->children->type != XML_ENTITY_DECL) && - (cur->children->type != XML_ENTITY_REF_NODE) && - (cur->children->type != XML_ENTITY_NODE)) - { - cur = cur->children; - continue; - } - } - - if (cur->next) { - cur = cur->next; - continue; + free(object->name); + free(object); + return E_OUTOFMEMORY; } + } - do - { - cur = cur->parent; - if (cur == NULL) - break; - if (cur == (xmlNodePtr) style->doc) { - cur = NULL; - break; - } - if (cur->next) { - cur = cur->next; - break; - } - } while (cur); + object->type = type; + switch (object->type) + { + case NODE_PROCESSING_INSTRUCTION: + if (!wcscmp(object->name, L"xml")) + object->flags |= DOMNODE_READONLY_VALUE; + break; + default: + ; } + + list_init(&object->entry); + list_init(&object->owner_entry); + list_init(&object->children); + list_init(&object->attributes); + list_init(&object->namespaces); + list_init(&object->owned); + object->owner = owner; + /* Document node does not have an owner */ + if (owner) + list_add_tail(&owner->owned, &object->owner_entry); + + *node = object; + + return S_OK; } -#undef XSLT_GET_IMPORT_PTR -#define XSLT_GET_IMPORT_PTR(res, style, name) { \ - xsltStylesheetPtr st = style; \ - res = NULL; \ - while (st != NULL) { \ - if (st->name != NULL) { res = st->name; break; } \ - st = xsltNextImport(st); \ - }} +static void domnode_append_attribute(struct domnode *parent, struct domnode *node) +{ + domnode_unlink_attribute(node); -#undef XSLT_GET_IMPORT_INT -#define XSLT_GET_IMPORT_INT(res, style, name) { \ - xsltStylesheetPtr st = style; \ - res = -1; \ - while (st != NULL) { \ - if (st->name != -1) { res = st->name; break; } \ - st = xsltNextImport(st); \ - }} + list_add_tail(&parent->attributes, &node->entry); + node->parent = parent; + domnode_add_refs(node->parent, node->refcount); + domnode_set_owner(node, parent); +} -static void transform_write_xmldecl(xmlDocPtr result, xsltStylesheetPtr style, BOOL omit_encoding, xmlOutputBufferPtr output) +static HRESULT parse_xml_decl_append_attribute(struct domnode *pi, const WCHAR *name, BSTR value) { - int omit_xmldecl, standalone; + struct domnode *attribute; + HRESULT hr; - XSLT_GET_IMPORT_INT(omit_xmldecl, style, omitXmlDeclaration); - if (omit_xmldecl == 1) return; + if (FAILED(hr = domnode_create(NODE_ATTRIBUTE, name, wcslen(name), NULL, 0, pi->owner, &attribute))) + return hr; - XSLT_GET_IMPORT_INT(standalone, style, standalone); + if (SUCCEEDED(hr = node_put_data(attribute, value))) + domnode_append_attribute(pi, attribute); + else + domnode_destroy_tree(attribute); - xmlOutputBufferWriteString(output, "<?xml version="); - if (result->version) - { - xmlOutputBufferWriteString(output, "\""); - xmlOutputBufferWriteString(output, (const char *)result->version); - xmlOutputBufferWriteString(output, "\""); - } + return hr; +} + +static HRESULT parse_xml_decl(struct domnode *pi, const WCHAR *data) +{ + BSTR version, encoding, standalone; + HRESULT hr; + + if (FAILED(hr = parse_xml_decl_body(data, &version, &encoding, &standalone))) + return hr; + + hr = parse_xml_decl_append_attribute(pi, L"version", version); + + if (SUCCEEDED(hr) && encoding) + hr = parse_xml_decl_append_attribute(pi, L"encoding", encoding); + + if (SUCCEEDED(hr) && standalone) + hr = parse_xml_decl_append_attribute(pi, L"standalone", standalone); + + SysFreeString(version); + SysFreeString(encoding); + SysFreeString(standalone); + + return hr; +} + +/* Parses declaration into attributes, public API does not allow setting data for such nodes. */ +HRESULT create_pi_node(struct domnode *doc, const WCHAR *target, const WCHAR *data, IXMLDOMProcessingInstruction **ret) +{ + struct domnode *pi; + HRESULT hr; + + if (!ret) + return E_INVALIDARG; + + if (!target || !*target) + return E_FAIL; + + *ret = NULL; + + if (FAILED(hr = domnode_create(NODE_PROCESSING_INSTRUCTION, target, wcslen(target), NULL, 0, doc, &pi))) + return hr; + + if (!wcscmp(target, L"xml")) + hr = parse_xml_decl(pi, data); else - xmlOutputBufferWriteString(output, "\"1.0\""); + hr = node_put_data(pi, data); - if (!omit_encoding) - { - const xmlChar *encoding; + if (SUCCEEDED(hr)) + return create_node(pi, (IXMLDOMNode **)ret); - /* default encoding is UTF-16 */ - XSLT_GET_IMPORT_PTR(encoding, style, encoding); - xmlOutputBufferWriteString(output, " encoding="); - xmlOutputBufferWriteString(output, "\""); - xmlOutputBufferWriteString(output, encoding ? (const char *)encoding : "UTF-16"); - xmlOutputBufferWriteString(output, "\""); - } + domnode_destroy_tree(pi); - /* standalone attribute */ - if (standalone != -1) - xmlOutputBufferWriteString(output, standalone == 0 ? " standalone=\"no\"" : " standalone=\"yes\""); + return hr; +} - xmlOutputBufferWriteString(output, "?>"); +HRESULT node_append_child(struct domnode *node, IXMLDOMNode *child, IXMLDOMNode **outChild) +{ + VARIANT var; + + VariantInit(&var); + return node_insert_before(node, child, &var, outChild); } -static void htmldtd_dumpcontent(xmlOutputBufferPtr buf, xmlDocPtr doc) +HRESULT node_has_childnodes(const struct domnode *node, VARIANT_BOOL *ret) { - xmlDtdPtr cur = doc->intSubset; + if (!ret) + return E_INVALIDARG; - xmlOutputBufferWriteString(buf, "<!DOCTYPE "); - xmlOutputBufferWriteString(buf, (const char *)cur->name); - if (cur->ExternalID) - { - xmlOutputBufferWriteString(buf, " PUBLIC "); - xml_write_quotedstring(buf, cur->ExternalID); - if (cur->SystemID) - { - xmlOutputBufferWriteString(buf, " "); - xml_write_quotedstring(buf, cur->SystemID); - } - } - else if (cur->SystemID) + if (list_empty(&node->children)) { - xmlOutputBufferWriteString(buf, " SYSTEM "); - xml_write_quotedstring(buf, cur->SystemID); + *ret = VARIANT_FALSE; + return S_FALSE; } - xmlOutputBufferWriteString(buf, ">\n"); + + *ret = VARIANT_TRUE; + return S_OK; } -/* Duplicates htmlDocContentDumpFormatOutput() the way we need it - doesn't add trailing newline. */ -static void htmldoc_dumpcontent(xmlOutputBufferPtr buf, xmlDocPtr doc, const char *encoding, int format) +HRESULT node_get_owner_document(const struct domnode *node, IXMLDOMDocument **doc) { - xmlElementType type; + IXMLDOMNode *node_obj; + HRESULT hr; - /* force HTML output */ - type = doc->type; - doc->type = XML_HTML_DOCUMENT_NODE; - if (doc->intSubset) - htmldtd_dumpcontent(buf, doc); - if (doc->children) { - xmlNodePtr cur = doc->children; - while (cur) { - htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format); - cur = cur->next; - } + if (!doc) + return E_INVALIDARG; + + if (FAILED(hr = get_node(node->owner, &node_obj))) + return hr; + + hr = IXMLDOMNode_QueryInterface(node_obj, &IID_IXMLDOMDocument, (void **)doc); + IXMLDOMNode_Release(node_obj); + + return hr; +} + +struct domnode *domnode_addref(struct domnode *node) +{ + domnode_add_refs(node, 1); + return node; +} + +static struct domnode *domnode_drop_refs(struct domnode *node, unsigned int count) +{ + struct domnode *top = NULL; + + if (node->owner) + node->owner->refcount -= count; + while (node) + { + top = node; + node->refcount -= count; + node = node->parent; } - doc->type = type; + + return top; } -static inline BOOL transform_is_empty_resultdoc(xmlDocPtr result) +struct domdoc_properties *domdoc_create_properties(MSXML_VERSION version) { - return !result->children || ((result->children->type == XML_DTD_NODE) && !result->children->next); + struct domdoc_properties *properties = malloc(sizeof(*properties)); + + list_init(&properties->selectNsList); + properties->preserving = VARIANT_FALSE; + properties->validating = VARIANT_TRUE; + properties->schemaCache = NULL; + properties->selectNsStr = calloc(1, sizeof(xmlChar)); + properties->selectNsStr_len = 0; + + /* properties that are dependent on object versions */ + properties->version = version; + properties->XPath = (version == MSXML4 || version == MSXML6); + + /* document uri */ + properties->uri = NULL; + + return properties; } -static inline BOOL transform_is_valid_method(xsltStylesheetPtr style) +static void domdoc_properties_destroy(struct domdoc_properties *properties) { - return !style->methodURI || !(style->method && xmlStrEqual(style->method, (const xmlChar *)"xhtml")); + if (properties->schemaCache) + IXMLDOMSchemaCollection2_Release(properties->schemaCache); + domdoc_properties_clear_selection_namespaces(&properties->selectNsList); + free((xmlChar*)properties->selectNsStr); + if (properties->uri) + IUri_Release(properties->uri); + free(properties); } -/* Helper to write transformation result to specified output buffer. */ -static HRESULT node_transform_write(xsltStylesheetPtr style, xmlDocPtr result, BOOL omit_encoding, const char *encoding, xmlOutputBufferPtr output) +static struct domdoc_properties* domdoc_properties_clone(struct domdoc_properties const* properties) { - const xmlChar *method; - int indent; + struct domdoc_properties* pcopy = malloc(sizeof(*pcopy)); + select_ns_entry const* ns = NULL; + select_ns_entry* new_ns = NULL; + int len = (properties->selectNsStr_len+1)*sizeof(xmlChar); + ptrdiff_t offset; - if (!transform_is_valid_method(style)) + if (pcopy) { - ERR("unknown output method\n"); - return E_FAIL; + pcopy->version = properties->version; + pcopy->preserving = properties->preserving; + pcopy->validating = properties->validating; + pcopy->schemaCache = properties->schemaCache; + if (pcopy->schemaCache) + IXMLDOMSchemaCollection2_AddRef(pcopy->schemaCache); + pcopy->XPath = properties->XPath; + pcopy->selectNsStr_len = properties->selectNsStr_len; + list_init( &pcopy->selectNsList ); + pcopy->selectNsStr = malloc(len); + memcpy((xmlChar*)pcopy->selectNsStr, properties->selectNsStr, len); + offset = pcopy->selectNsStr - properties->selectNsStr; + + LIST_FOR_EACH_ENTRY( ns, (&properties->selectNsList), select_ns_entry, entry ) + { + new_ns = malloc(sizeof(select_ns_entry)); + memcpy(new_ns, ns, sizeof(select_ns_entry)); + new_ns->href += offset; + new_ns->prefix += offset; + list_add_tail(&pcopy->selectNsList, &new_ns->entry); + } + + pcopy->uri = properties->uri; + if (pcopy->uri) + IUri_AddRef(pcopy->uri); } - XSLT_GET_IMPORT_PTR(method, style, method) - XSLT_GET_IMPORT_INT(indent, style, indent); + return pcopy; +} - if (!method && (result->type == XML_HTML_DOCUMENT_NODE)) - method = (const xmlChar *) "html"; +void domnode_destroy_tree(struct domnode *tree) +{ + struct domnode *node, *next; - if (method && xmlStrEqual(method, (const xmlChar *)"html")) - { - htmlSetMetaEncoding(result, (const xmlChar *)encoding); - if (indent == -1) - indent = 1; - htmldoc_dumpcontent(output, result, encoding, indent); - } - else if (method && xmlStrEqual(method, (const xmlChar *)"xhtml")) + if (tree->type == NODE_DOCUMENT) { - htmlSetMetaEncoding(result, (const xmlChar *) encoding); - htmlDocContentDumpOutput(output, result, encoding); + /* For the document nodes we can skip hierarchical calls, + since all the nodes are in the owner list. */ + + LIST_FOR_EACH_ENTRY_SAFE(node, next, &tree->owned, struct domnode, owner_entry) + { + list_remove(&node->owner_entry); + node->owner = NULL; + list_init(&node->children); + list_init(&node->attributes); + domnode_destroy_tree(node); + } + domdoc_properties_destroy(tree->properties); + tree->properties = NULL; } - else if (method && xmlStrEqual(method, (const xmlChar *)"text")) - transform_write_text(result, style, output); else { - transform_write_xmldecl(result, style, omit_encoding, output); + list_remove(&tree->owner_entry); - if (result->children) + LIST_FOR_EACH_ENTRY_SAFE(node, next, &tree->children, struct domnode, entry) { - xmlNodePtr child = result->children; + list_remove(&node->entry); + node->parent = NULL; + domnode_destroy_tree(node); + } - while (child) - { - xmlNodeDumpOutput(output, result, child, 0, indent == 1, encoding); - if (indent && ((child->type == XML_DTD_NODE) || ((child->type == XML_COMMENT_NODE) && child->next))) - xmlOutputBufferWriteString(output, "\r\n"); - child = child->next; - } + LIST_FOR_EACH_ENTRY_SAFE(node, next, &tree->attributes, struct domnode, entry) + { + list_remove(&node->entry); + domnode_destroy_tree(node); } } - xmlOutputBufferFlush(output); - return S_OK; -} - -/* For BSTR output is always UTF-16, without 'encoding' attribute */ -static HRESULT node_transform_write_to_bstr(xsltStylesheetPtr style, xmlDocPtr result, BSTR *str) -{ - HRESULT hr = S_OK; - - if (transform_is_empty_resultdoc(result)) - *str = SysAllocStringLen(NULL, 0); - else + if (tree->prefix) { - xmlOutputBufferPtr output = xmlAllocOutputBuffer(xmlFindCharEncodingHandler("UTF-16")); - const xmlChar *content; - size_t len; + SysFreeString(tree->prefix); + SysFreeString(tree->qname); + } + SysFreeString(tree->name); + SysFreeString(tree->data); + SysFreeString(tree->uri); - *str = NULL; - if (!output) - return E_OUTOFMEMORY; + free(tree); +} - hr = node_transform_write(style, result, TRUE, "UTF-16", output); - content = xmlBufContent(output->conv); - len = xmlBufUse(output->conv); - /* UTF-16 encoder places UTF-16 bom, we don't need it for BSTR */ - content += sizeof(WCHAR); - *str = SysAllocStringLen((WCHAR*)content, len/sizeof(WCHAR) - 1); - xmlOutputBufferClose(output); - } +void domnode_release(struct domnode *node) +{ + struct domnode *top; - return *str ? hr : E_OUTOFMEMORY; + top = domnode_drop_refs(node, 1); + if (top->refcount == 0) + domnode_destroy_tree(top); } -static HRESULT node_transform_write_to_stream(xsltStylesheetPtr style, xmlDocPtr result, ISequentialStream *stream) +HRESULT node_clone_domnode(struct domnode *node, bool deep, struct domnode **cloned) { - static const xmlChar *utf16 = (const xmlChar*)"UTF-16"; - xmlOutputBufferPtr output; - const xmlChar *encoding; + struct domnode *object, *n, *child; HRESULT hr; - if (transform_is_empty_resultdoc(result)) + *cloned = NULL; + + if (FAILED(hr = domnode_create(node->type, node->name, SysStringLen(node->name), node->uri, SysStringLen(node->uri), + node->owner, &object))) { - WARN("empty result document\n"); - return S_OK; + return hr; } - if (style->methodURI && (!style->method || !xmlStrEqual(style->method, (const xmlChar *) "xhtml"))) + if (node->type == NODE_DOCUMENT) + object->properties = domdoc_properties_clone(node->properties); + + if (deep) { - ERR("unknown output method\n"); - return E_FAIL; + LIST_FOR_EACH_ENTRY(n, &node->children, struct domnode, entry) + { + node_clone_domnode(n, true, &child); + domnode_append_child(object, child); + } } - /* default encoding is UTF-16 */ - XSLT_GET_IMPORT_PTR(encoding, style, encoding); - if (!encoding) - encoding = utf16; + LIST_FOR_EACH_ENTRY(n, &node->attributes, struct domnode, entry) + { + node_clone_domnode(n, true, &child); + domnode_append_attribute(object, child); + } - output = xmlOutputBufferCreateIO(transform_to_stream_write, NULL, stream, xmlFindCharEncodingHandler((const char*)encoding)); - if (!output) - return E_OUTOFMEMORY; + *cloned = object; - hr = node_transform_write(style, result, FALSE, (const char*)encoding, output); - xmlOutputBufferClose(output); return hr; } -struct import_buffer -{ - char *data; - int cur; - int len; -}; - -static int XMLCALL import_loader_io_read(void *context, char *out, int len) +HRESULT node_clone(struct domnode *node, VARIANT_BOOL deep, IXMLDOMNode **out) { - struct import_buffer *buffer = (struct import_buffer *)context; + struct domnode *cloned_node; + HRESULT hr; - TRACE("%p, %p, %d\n", context, out, len); + if (!out) + return E_INVALIDARG; - if (buffer->cur == buffer->len) - return 0; + *out = NULL; - len = min(len, buffer->len - buffer->cur); - memcpy(out, &buffer->data[buffer->cur], len); - buffer->cur += len; + if (FAILED(hr = node_clone_domnode(node, !!deep, &cloned_node))) + return hr; - TRACE("read %d\n", len); + if (FAILED(hr = create_node(cloned_node, out))) + domnode_destroy_tree(cloned_node); - return len; + return hr; } -static int XMLCALL import_loader_io_close(void * context) +static bool is_preserving_whitespace(const struct domnode *node) { - struct import_buffer *buffer = (struct import_buffer *)context; + const struct domnode *doc = node->owner ? node->owner : node; + struct domnode *attr; + BSTR value; + bool ret; - TRACE("%p\n", context); + /* Document-wide property */ + if (doc->properties->preserving == VARIANT_TRUE) + return true; - free(buffer->data); - free(buffer); - return 0; + if (node->type != NODE_ELEMENT) + return false; + + while (node) + { + if (domnode_get_qualified_attribute(node, L"space", + L"http://www.w3.org/XML/1998/namespace", &attr) == S_OK) + { + if (node_get_text(attr, &value) == S_OK) + { + ret = !wcscmp(value, L"preserve"); + SysFreeString(value); + return ret; + } + } + + node = node->parent; + } + + return false; } -static HRESULT import_loader_onDataAvailable(void *ctxt, char *ptr, DWORD len) +struct node_get_text_context { - xmlParserInputPtr *input = (xmlParserInputPtr *)ctxt; - xmlParserInputBufferPtr inputbuffer; - struct import_buffer *buffer; + struct string_buffer buffer; + bool first_textual_child; + bool preserve; + bool ignored_ws; + int depth; +}; - buffer = malloc(sizeof(*buffer)); +/* Trim leading and trailing white spaces */ +static WCHAR *domnode_get_text_trim(WCHAR *text, UINT *length) +{ + WCHAR *start = text; + UINT len = *length; - buffer->data = malloc(len); - memcpy(buffer->data, ptr, len); - buffer->cur = 0; - buffer->len = len; + while (start && xml_is_space(*start)) + { + ++start; + --len; + } - inputbuffer = xmlParserInputBufferCreateIO(import_loader_io_read, import_loader_io_close, buffer, - XML_CHAR_ENCODING_NONE); - *input = xmlNewIOInputStream(NULL, inputbuffer, XML_CHAR_ENCODING_NONE); - if (!*input) - xmlFreeParserInputBuffer(inputbuffer); + while (len && xml_is_space(start[len - 1])) + --len; - return *input ? S_OK : E_FAIL; + *length = len; + return start; } -static HRESULT xslt_doc_get_uri(const xmlChar *uri, void *_ctxt, xsltLoadType type, IUri **doc_uri) +static const WCHAR *domnode_get_text_trim_leading(const WCHAR *text, UINT *length) { - xsltStylesheetPtr style = (xsltStylesheetPtr)_ctxt; - IUri *href_uri; - HRESULT hr; - BSTR uriW; - - *doc_uri = NULL; + const WCHAR *start = text; + UINT len = *length; - uriW = bstr_from_xmlChar(uri); - hr = CreateUri(uriW, Uri_CREATE_ALLOW_RELATIVE | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &href_uri); - SysFreeString(uriW); - if (FAILED(hr)) + while (start && xml_is_space(*start)) { - WARN("Failed to create href uri, %#lx.\n", hr); - return hr; + ++start; + --len; } - if (type == XSLT_LOAD_STYLESHEET && style->doc && style->doc->name) - { - IUri *base_uri; - BSTR baseuriW; + *length = len; + return start; +} - baseuriW = bstr_from_xmlChar((xmlChar *)style->doc->name); - hr = CreateUri(baseuriW, Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &base_uri); - SysFreeString(baseuriW); - if (FAILED(hr)) +static void domnode_get_text_trim_trailing(struct string_buffer *buffer) +{ + while (buffer->count && xml_is_space(buffer->data[buffer->count - 1])) + --buffer->count; +} + +static void domnode_append_ignored(const struct domnode *node, unsigned int flags, struct node_get_text_context *context) +{ + /* Skip all leading ignored space */ + if (!context->buffer.count) + return; + + if (!context->ignored_ws && (node->flags & flags)) + { + context->ignored_ws = true; + if (!context->first_textual_child || context->preserve) { - WARN("Failed to create base uri, %#lx.\n", hr); - return hr; + string_append(&context->buffer, L" ", 1); + context->first_textual_child = false; } + } +} - hr = CoInternetCombineIUri(base_uri, href_uri, 0, doc_uri, 0); - IUri_Release(base_uri); - if (FAILED(hr)) - WARN("Failed to combine uris, hr %#lx.\n", hr); +static void domnode_append_ignored_pre(struct domnode *node, struct node_get_text_context *context) +{ + struct domnode *sibling = domnode_get_previous_sibling(node); + + if (sibling) + { + if (sibling->type == NODE_ELEMENT) + return domnode_append_ignored(sibling, DOMNODE_IGNORED_WS, context); } - else + else if (node->parent && node->parent->type == NODE_ELEMENT) { - *doc_uri = href_uri; - IUri_AddRef(*doc_uri); + domnode_append_ignored(node, DOMNODE_IGNORED_WS_AFTER_STARTTAG, context); } +} - IUri_Release(href_uri); +static bool is_space_data(const WCHAR *data) +{ + while (*data) + { + if (!xml_is_space(*data)) return false; + ++data; + } - return hr; + return true; } -xmlDocPtr xslt_doc_default_loader(const xmlChar *uri, xmlDictPtr dict, int options, - void *_ctxt, xsltLoadType type) +static void domnode_get_text(const struct domnode *node, struct node_get_text_context *context) { - IUri *import_uri = NULL; - xmlParserInputPtr input; - xmlParserCtxtPtr pctxt; - xmlDocPtr doc = NULL; - IMoniker *moniker; - HRESULT hr; - bsc_t *bsc; - BSTR uriW; + struct string_buffer *buffer = &context->buffer; + struct domnode *child; + const WCHAR *start; + UINT length; - TRACE("%s, %p, %#x, %p, %d\n", debugstr_a((const char *)uri), dict, options, _ctxt, type); + switch (node->type) + { + case NODE_TEXT: + if (context->first_textual_child && !context->preserve) + { + length = SysStringLen(node->data); + start = domnode_get_text_trim_leading(node->data, &length); + string_append(&context->buffer, start, length); + } + else if (!context->preserve && is_space_data(node->data)) + { + string_append(&context->buffer, L" ", 1); + } + else + { + string_append(&context->buffer, node->data, SysStringLen(node->data)); + } + context->first_textual_child = false; + context->ignored_ws = false; + break; - pctxt = xmlNewParserCtxt(); - if (!pctxt) - return NULL; + case NODE_CDATA_SECTION: + string_append(buffer, node->data, SysStringLen(node->data)); + context->first_textual_child = false; + context->ignored_ws = false; + break; - if (dict && pctxt->dict) - { - xmlDictFree(pctxt->dict); - pctxt->dict = NULL; - } + case NODE_ELEMENT: + LIST_FOR_EACH_ENTRY(child, &node->children, struct domnode, entry) + { + domnode_append_ignored_pre(child, context); + if (child->type == NODE_ELEMENT) ++context->depth; + domnode_get_text(child, context); + if (child->type == NODE_ELEMENT) --context->depth; + } + break; - if (dict) - { - pctxt->dict = dict; - xmlDictReference(pctxt->dict); + default: + ; } +} - xmlCtxtUseOptions(pctxt, options); +HRESULT node_get_text(const struct domnode *node, BSTR *text) +{ + struct node_get_text_context context = { 0 }; + struct domnode *child; + const WCHAR *start; + UINT length; - hr = xslt_doc_get_uri(uri, _ctxt, type, &import_uri); - if (FAILED(hr)) - goto failed; + string_buffer_init(&context.buffer); + context.preserve = is_preserving_whitespace(node); + switch (node->type) + { + case NODE_COMMENT: + case NODE_ENTITY_REFERENCE: + case NODE_CDATA_SECTION: + return return_bstr(node->data, text); - hr = CreateURLMonikerEx2(NULL, import_uri, &moniker, 0); - if (FAILED(hr)) - goto failed; + case NODE_PROCESSING_INSTRUCTION: + return node_get_pi_data(node, text); - hr = bind_url(moniker, import_loader_onDataAvailable, &input, &bsc); - IMoniker_Release(moniker); - if (FAILED(hr)) - goto failed; + case NODE_TEXT: + if (context.preserve) + { + string_append(&context.buffer, node->data, SysStringLen(node->data)); + } + else + { + length = SysStringLen(node->data); + start = domnode_get_text_trim(node->data, &length); + string_append(&context.buffer, start, length); + } + return string_to_bstr(&context.buffer, text); - if (FAILED(detach_bsc(bsc))) - goto failed; + case NODE_ATTRIBUTE: + LIST_FOR_EACH_ENTRY(child, &node->children, struct domnode, entry) + { + string_append(&context.buffer, child->data, SysStringLen(child->data)); + } + return string_to_bstr(&context.buffer, text); - if (!input) - goto failed; + case NODE_DOCUMENT: + case NODE_DOCUMENT_FRAGMENT: - inputPush(pctxt, input); - xmlParseDocument(pctxt); + context.first_textual_child = true; + LIST_FOR_EACH_ENTRY(child, &node->children, struct domnode, entry) + { + domnode_get_text(child, &context); + } + if (!context.preserve) + domnode_get_text_trim_trailing(&context.buffer); + return string_to_bstr(&context.buffer, text); - if (pctxt->wellFormed) - { - doc = pctxt->myDoc; - /* Set imported uri, to give nested imports a chance. */ - if (IUri_GetPropertyBSTR(import_uri, Uri_PROPERTY_ABSOLUTE_URI, &uriW, 0) == S_OK) - { - doc->name = (char *)xmlchar_from_wcharn(uriW, SysStringLen(uriW), TRUE); - SysFreeString(uriW); - } - } - else - { - doc = NULL; - xmlFreeDoc(pctxt->myDoc); - pctxt->myDoc = NULL; - } + case NODE_ELEMENT: -failed: - xmlFreeParserCtxt(pctxt); - if (import_uri) - IUri_Release(import_uri); + /* Trim leading spaces of the first textual node. Append everything else as is, + then trim trailing spaces. */ - return doc; -} + context.first_textual_child = true; + domnode_get_text(node, &context); + if (!context.preserve) + domnode_get_text_trim_trailing(&context.buffer); + return string_to_bstr(&context.buffer, text); -#ifdef _WIN64 + default: + FIXME("not implemented for node type %d\n", node->type); + return E_NOTIMPL; + } +} -#define IActiveScriptParse_Release IActiveScriptParse64_Release -#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew -#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText +HRESULT node_get_preserved_text(const struct domnode *node, BSTR *text) +{ + struct node_get_text_context context = { 0 }; -#else + string_buffer_init(&context.buffer); + context.preserve = true; -#define IActiveScriptParse_Release IActiveScriptParse32_Release -#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew -#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText + switch (node->type) + { + case NODE_ELEMENT: + domnode_get_text(node, &context); + return string_to_bstr(&context.buffer, text); -#endif + default: + FIXME("not implemented for node type %d\n", node->type); + return E_NOTIMPL; + } +} -struct xsl_scripts +HRESULT node_get_value(struct domnode *node, VARIANT *value) { - struct + if (!value) + return E_INVALIDARG; + + switch (node->type) { - IActiveScript *script; - const xmlChar *uri; - } *entries; - size_t count; - size_t capacity; -}; + case NODE_TEXT: + case NODE_CDATA_SECTION: + case NODE_ATTRIBUTE: + case NODE_PROCESSING_INSTRUCTION: + case NODE_COMMENT: + V_VT(value) = VT_BSTR; + return node_get_text(node, &V_BSTR(value)); + default: + FIXME("Unsupported type %d.\n", node->type); + return E_NOTIMPL; + } +} -static IActiveScript *xpath_msxsl_script_get_script(xmlXPathParserContextPtr ctxt, const xmlChar *uri) +static void node_dump_xml_text(struct domnode *node, struct node_dump_context *context) { - xsltTransformContextPtr xslt_ctxt = xsltXPathGetTransformContext(ctxt); - struct xsl_scripts *scripts = xslt_ctxt->userData; + BSTR p = node->data; - for (size_t i = 0; i < scripts->count; ++i) + while (p && *p) { - if (xmlStrEqual(scripts->entries[i].uri, uri)) - return scripts->entries[i].script; + if (*p == '<') + node_dump_append(context, L"<", 4); + else if (*p == '>') + node_dump_append(context, L">", 4); + else if (*p == '&') + node_dump_append(context, L"&", 5); + else if (*p == '\n') + node_dump_append(context, L"\r\n", 2); + else + node_dump_append(context, p, 1); + ++p; } - - return NULL; } -static HRESULT xpath_create_nodelist_from_set(xmlNodeSetPtr set, bool needs_copy, IXMLDOMNodeList **ret) +static void node_dump_xml_attr(struct domnode *node, struct node_dump_context *context) { - xmlNodeSet _copy = { 0 }; - xmlXPathObjectPtr obj; - HRESULT hr; + BSTR p = node->data; - if (needs_copy) + while (p && *p) { - _copy.nodeTab = xmlMalloc(set->nodeNr * sizeof(*set->nodeTab)); - _copy.nodeNr = set->nodeNr; - _copy.nodeMax = set->nodeNr; - for (int i = 0; i < set->nodeNr; ++i) - _copy.nodeTab[i] = xmlCopyNode(set->nodeTab[i], 1); - set = &_copy; + if (*p == '<') + node_dump_append(context, L"<", 4); + else if (*p == '>') + node_dump_append(context, L">", 4); + else if (*p == '&') + node_dump_append(context, L"&", 5); + else if (*p == '"') + node_dump_append(context, L""", 6); + else + node_dump_append(context, p, 1); + ++p; } - - obj = xmlXPathNewNodeSetList(set); - hr = create_selection_from_nodeset(obj, ret); - xmlFree(_copy.nodeTab); - - return hr; } -static void xpath_msxsl_script_function(xmlXPathParserContextPtr ctxt, int nargs) +static void node_dump_xml(struct domnode *node, struct node_dump_context *context) { - xsltTransformContextPtr xslt_ctxt = xsltXPathGetTransformContext(ctxt); - xmlXPathContextPtr xpath = ((struct _xsltTransformContext *)xslt_ctxt)->xpathCtxt; - DISPPARAMS params = { 0 }; - IActiveScript *script; - VARIANT *args = NULL; - IDispatch *disp; - VARIANT result; - DISPID dispid; - HRESULT hr; - BSTR name; - - TRACE("%s:%s\n", xpath->functionURI, xpath->function); + struct string_buffer *buffer = &context->buffer; + BSTR p = node->data; - script = xpath_msxsl_script_get_script(ctxt, xpath->functionURI); - if (!script) + while (p && *p) { - WARN("Couldn't find a script for %s.\n", xpath->functionURI); - return; + if (*p == '\n') + string_append(buffer, L"\r\n", 2); + else + string_append(buffer, p, 1); + ++p; } +} - if (FAILED(IActiveScript_GetScriptDispatch(script, NULL, &disp))) - return; +static void node_dump_pi(struct domnode *node, struct node_dump_context *context) +{ + VARIANT value; - name = bstr_from_xmlChar(xpath->function); - hr = IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, &dispid); - SysFreeString(name); - if (FAILED(hr)) + node_dump_append(context, L"<?", 2); + node_dump_append(context, node->name, SysStringLen(node->name)); + if (!wcscmp(node->name, L"xml")) { - WARN("Couldn't find %s function.\n", xpath->function); - IDispatch_Release(disp); - return; - } + /* Make sure attributes are in correct order. */ - if (nargs) - { - args = calloc(nargs, sizeof(*args)); + node_dump_append(context, L" version=\"", 10); + if (node_get_attribute_value(node, L"version", &value) == S_OK) + { + node_dump_append(context, V_BSTR(&value), SysStringLen(V_BSTR(&value))); + VariantClear(&value); + } + else + { + node_dump_append(context, L"1.0", 3); + } + node_dump_append(context, L"\"", 1); - for (int i = 0; i < nargs; ++i) + if (node_get_attribute_value(node, L"encoding", &value) == S_OK) { - xmlXPathObjectType obj_type = XPATH_UNDEFINED; - xmlXPathObjectPtr obj = NULL; - xmlChar *s; + if ((context->only_utf16_encoding_decl && !wcsicmp(V_BSTR(&value), L"UTF-16")) + || !context->only_utf16_encoding_decl) + { + node_dump_append(context, L" encoding=\"", 11); + node_dump_append(context, V_BSTR(&value), SysStringLen(V_BSTR(&value))); + node_dump_append(context, L"\"", 1); + } + VariantClear(&value); + } - /* Since we don't want to impose expectations on argument types, - first inspect actual type on stack, and then pop with corresponding function. */ - if (ctxt->valueNr > 0) - { - obj = ctxt->valueTab[ctxt->valueNr - 1]; - obj_type = obj->type; - } + if (node_get_attribute_value(node, L"standalone", &value) == S_OK) + { + node_dump_append(context, L" standalone=\"", 13); + node_dump_append(context, V_BSTR(&value), SysStringLen(V_BSTR(&value))); + node_dump_append(context, L"\"", 1); + VariantClear(&value); + } + } + else + { + node_dump_append(context, L" ", 1); + node_dump_xml(node, context); + } + node_dump_append(context, L"?>", 2); +} - switch (obj_type) - { - case XPATH_XSLT_TREE: - case XPATH_NODESET: - { - xmlNodeSetPtr nodeset = xmlXPathPopNodeSet(ctxt); - IXMLDOMNodeList *nodelist; +static void node_dump_format(struct node_dump_context *context) +{ + struct string_buffer *buffer = &context->buffer; + unsigned int indent = context->indent; - hr = xpath_create_nodelist_from_set(nodeset, obj_type == XPATH_XSLT_TREE, &nodelist); + if (!context->needs_formatting) + return; - V_VT(&args[i]) = VT_DISPATCH; - V_DISPATCH(&args[i]) = (IDispatch *)nodelist; - break; - } - case XPATH_STRING: - s = xmlXPathPopString(ctxt); - V_VT(&args[i]) = VT_BSTR; - V_BSTR(&args[i]) = bstr_from_xmlChar(s); - xmlFree(s); - break; - case XPATH_NUMBER: - V_VT(&args[i]) = VT_R8; - V_R8(&args[i]) = xmlXPathPopNumber(ctxt); - break; - case XPATH_BOOLEAN: - V_VT(&args[i]) = VT_BOOL; - V_BOOL(&args[i]) = xmlXPathPopBoolean(ctxt) ? VARIANT_TRUE : VARIANT_FALSE; - break; - default: - FIXME("Unexpected XPath (%s) value type %d.\n", xpath->function, obj->type); - return; - } - } + string_append(buffer, L"\r\n", 2); - params.rgvarg = args; - params.cArgs = nargs; + while (indent--) + { + string_append(buffer, L"\t", 1); } +} - VariantInit(&result); - hr = IDispatch_Invoke(disp, dispid, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, &result, NULL, NULL); - if (FAILED(hr)) - WARN("User script Invoke() failed %#lx, function %s.\n", hr, xpath->function); +static void node_dump_qualified_name(struct node_dump_context *context, struct domnode *node) +{ + node_dump_append(context, node->qname, SysStringLen(node->qname)); +} - if (args) +static bool is_same_namespace_prefix(const struct domnode *node, const WCHAR *prefix) +{ + if (node->prefix) + return prefix && !wcscmp(node->prefix, prefix); + + return !prefix; +} + +static bool is_namespace_definition(struct domnode *node) +{ + if (!wcscmp(node->qname, L"xmlns")) + return true; + if (is_same_namespace_prefix(node, L"xmlns")) + return true; + return false; +} + +static bool is_namespace_defined(struct node_dump_context *context, struct domnode *node) +{ + struct node_dump_ns *ns; + + if (!node->uri) + return true; + + /* The xmlns:xml namespace is predefined. */ + if (is_same_namespace_prefix(node, L"xml")) + return true; + + LIST_FOR_EACH_ENTRY_REV(ns, &context->namespaces, struct node_dump_ns, entry) { - for (int i = 0; i < nargs; ++i) - VariantClear(&args[i]); - free(args); + if (is_same_namespace_prefix(node, ns->prefix)) + return !wcscmp(node->uri, ns->uri); } - switch (V_VT(&result)) + return false; +} + +static void node_dump_namespace_for_node(struct node_dump_context *context, struct domnode *node) +{ + node_dump_push_namespace(context, node->prefix, node->uri, false); + node_dump_append(context, L" xmlns", 6); + if (node->prefix) { - case VT_BSTR: + node_dump_append(context, L":", 1); + node_dump_append(context, node->prefix, SysStringLen(node->prefix)); + } + node_dump_append(context, L"=\"", 2); + node_dump_append(context, node->uri, SysStringLen(node->uri)); + node_dump_append(context, L"\"", 1); +} + +static WCHAR *node_dump_get_namespace_prefix(struct domnode *attr) +{ + return attr->prefix ? attr->name : NULL; +} + +static void node_dump_element_attributes(struct node_dump_context *context, struct domnode *node) +{ + struct domnode *attr; + BSTR text; + + /* Collect explicitly defined namespaces */ + LIST_FOR_EACH_ENTRY(attr, &node->attributes, struct domnode, entry) + { + if (is_namespace_definition(attr)) { - xmlChar *s = xmlchar_from_wcharn(V_BSTR(&result), -1, TRUE); - xmlXPathReturnString(ctxt, s); - break; + node_get_text(attr, &text); + node_dump_push_namespace(context, node_dump_get_namespace_prefix(attr), text, true); } - case VT_BOOL: - xmlXPathReturnBoolean(ctxt, !!V_BOOL(&result)); + } + + /* If namespace is implied, check if it's been defined already. This needs to be done for + the element too. */ + + if (!is_namespace_defined(context, node)) + node_dump_namespace_for_node(context, node); + + LIST_FOR_EACH_ENTRY(attr, &node->attributes, struct domnode, entry) + { + if (is_namespace_definition(attr)) + continue; + + if (!is_namespace_defined(context, attr)) + node_dump_namespace_for_node(context, attr); + } + + LIST_FOR_EACH_ENTRY(attr, &node->attributes, struct domnode, entry) + { + node_dump_append(context, L" ", 1); + node_dump(attr, context); + } +} + +static void node_dump(struct domnode *node, struct node_dump_context *context) +{ + struct domnode *n; + + switch (node->type) + { + case NODE_COMMENT: + node_dump_format(context); + node_dump_append(context, L"<!--", 4); + node_dump_xml(node, context); + node_dump_append(context, L"-->", 3); + context->needs_formatting = node->flags & DOMNODE_IGNORED_WS; break; - case VT_INT: - case VT_I1: - case VT_UI1: - case VT_I2: - case VT_UI2: - case VT_I4: - case VT_UI4: - case VT_R4: - case VT_R8: - VariantChangeType(&result, &result, 0, VT_R8); - xmlXPathReturnNumber(ctxt, V_R8(&result)); + + case NODE_PROCESSING_INSTRUCTION: + node_dump_format(context); + node_dump_pi(node, context); + context->needs_formatting = node->flags & DOMNODE_IGNORED_WS; break; - case VT_EMPTY: - xmlXPathReturnEmptyString(ctxt); + + case NODE_TEXT: + node_dump_xml_text(node, context); + context->needs_formatting = false; + break; + + case NODE_CDATA_SECTION: + node_dump_format(context); + node_dump_append(context, L"<![CDATA[", 9); + node_dump_xml(node, context); + node_dump_append(context, L"]]>", 3); + context->needs_formatting = node->flags & DOMNODE_IGNORED_WS; + break; + + case NODE_ELEMENT: + node_dump_format(context); + node_dump_append(context, L"<", 1); + node_dump_qualified_name(context, node); + node_dump_element_attributes(context, node); + if (list_empty(&node->children)) + { + node_dump_append(context, L"/>", 2); + } + else + { + node_dump_append(context, L">", 1); + + ++context->depth; + ++context->indent; + context->needs_formatting = node->flags & DOMNODE_IGNORED_WS_AFTER_STARTTAG; + LIST_FOR_EACH_ENTRY(n, &node->children, struct domnode, entry) + { + node_dump(n, context); + } + --context->indent; + --context->depth; + + node_dump_format(context); + node_dump_append(context, L"</", 2); + node_dump_qualified_name(context, node); + node_dump_append(context, L">", 1); + } + node_dump_pop_namespaces(context); + context->needs_formatting = node->flags & DOMNODE_IGNORED_WS; + break; + + case NODE_DOCUMENT_FRAGMENT: + LIST_FOR_EACH_ENTRY(n, &node->children, struct domnode, entry) + { + node_dump(n, context); + } + break; + + case NODE_ATTRIBUTE: + node_dump_qualified_name(context, node); + node_dump_append(context, L"=\"", 2); + LIST_FOR_EACH_ENTRY(n, &node->children, struct domnode, entry) + { + node_dump_xml_attr(n, context); + } + node_dump_append(context, L"\"", 1); break; + + case NODE_ENTITY_REFERENCE: + node_dump_append(context, L"&", 1); + node_dump_append(context, node->name, SysStringLen(node->name)); + node_dump_append(context, L";", 1); + break; + + case NODE_DOCUMENT_TYPE: + node_dump_append(context, node->data, SysStringLen(node->data)); + break; + default: - FIXME("Unexpected return value %s.\n", debugstr_variant(&result)); - xmlXPathReturnEmptyString(ctxt); + FIXME("Unimplemented for type %d.\n", node->type); + context->status = E_NOTIMPL; + break; + } +} + +static void node_dump_context_init(struct node_dump_context *context, UINT codepage, IStream *stream) +{ + memset(context, 0, sizeof(*context)); + string_buffer_init(&context->buffer); + list_init(&context->namespaces); + context->buffer.status = &context->status; + context->codepage = codepage; + context->stream = stream; +} + +static HRESULT node_dump_context_cleanup(struct node_dump_context *context) +{ + HRESULT status = context->status; + + free(context->scratch.data); + return status; +} + +HRESULT node_get_xml(struct domnode *node, BSTR *ret) +{ + struct node_dump_context context; + struct domnode *n; + + if (!ret) + return E_INVALIDARG; + + node_dump_context_init(&context, ~0u, NULL); + context.only_utf16_encoding_decl = true; + + if (node->type == NODE_DOCUMENT) + { + LIST_FOR_EACH_ENTRY(n, &node->children, struct domnode, entry) + { + node_dump(n, &context); + node_dump_append(&context, L"\r\n", 2); + } + } + else + { + node_dump(node, &context); + } + return string_to_bstr(&context.buffer, ret); +} + +/* duplicates xmlBufferWriteQuotedString() logic */ +static void xml_write_quotedstring(xmlOutputBufferPtr buf, const xmlChar *string) +{ + const xmlChar *cur, *base; + + if (xmlStrchr(string, '\"')) + { + if (xmlStrchr(string, '\'')) + { + xmlOutputBufferWrite(buf, 1, "\""); + base = cur = string; + + while (*cur) + { + if (*cur == '"') + { + if (base != cur) + xmlOutputBufferWrite(buf, cur-base, (const char*)base); + xmlOutputBufferWrite(buf, 6, """); + cur++; + base = cur; + } + else + cur++; + } + if (base != cur) + xmlOutputBufferWrite(buf, cur-base, (const char*)base); + xmlOutputBufferWrite(buf, 1, "\""); + } + else + { + xmlOutputBufferWrite(buf, 1, "\'"); + xmlOutputBufferWriteString(buf, (const char*)string); + xmlOutputBufferWrite(buf, 1, "\'"); + } + } + else + { + xmlOutputBufferWrite(buf, 1, "\""); + xmlOutputBufferWriteString(buf, (const char*)string); + xmlOutputBufferWrite(buf, 1, "\""); + } +} + +static int XMLCALL transform_to_stream_write(void *context, const char *buffer, int len) +{ + DWORD written; + HRESULT hr = ISequentialStream_Write((ISequentialStream *)context, buffer, len, &written); + return hr == S_OK ? written : -1; +} + +/* Output for method "text" */ +static void transform_write_text(xmlDocPtr result, xsltStylesheetPtr style, xmlOutputBufferPtr output) +{ + xmlNodePtr cur = result->children; + while (cur) + { + if (cur->type == XML_TEXT_NODE) + xmlOutputBufferWriteString(output, (const char*)cur->content); + + /* skip to next node */ + if (cur->children) + { + if ((cur->children->type != XML_ENTITY_DECL) && + (cur->children->type != XML_ENTITY_REF_NODE) && + (cur->children->type != XML_ENTITY_NODE)) + { + cur = cur->children; + continue; + } + } + + if (cur->next) { + cur = cur->next; + continue; + } + + do + { + cur = cur->parent; + if (cur == NULL) + break; + if (cur == (xmlNodePtr) style->doc) { + cur = NULL; + break; + } + if (cur->next) { + cur = cur->next; + break; + } + } while (cur); + } +} + +#undef XSLT_GET_IMPORT_PTR +#define XSLT_GET_IMPORT_PTR(res, style, name) { \ + xsltStylesheetPtr st = style; \ + res = NULL; \ + while (st != NULL) { \ + if (st->name != NULL) { res = st->name; break; } \ + st = xsltNextImport(st); \ + }} + +#undef XSLT_GET_IMPORT_INT +#define XSLT_GET_IMPORT_INT(res, style, name) { \ + xsltStylesheetPtr st = style; \ + res = -1; \ + while (st != NULL) { \ + if (st->name != -1) { res = st->name; break; } \ + st = xsltNextImport(st); \ + }} + +static void transform_write_xmldecl(xmlDocPtr result, xsltStylesheetPtr style, BOOL omit_encoding, xmlOutputBufferPtr output) +{ + int omit_xmldecl, standalone; + + XSLT_GET_IMPORT_INT(omit_xmldecl, style, omitXmlDeclaration); + if (omit_xmldecl == 1) return; + + XSLT_GET_IMPORT_INT(standalone, style, standalone); + + xmlOutputBufferWriteString(output, "<?xml version="); + if (result->version) + { + xmlOutputBufferWriteString(output, "\""); + xmlOutputBufferWriteString(output, (const char *)result->version); + xmlOutputBufferWriteString(output, "\""); + } + else + xmlOutputBufferWriteString(output, "\"1.0\""); + + if (!omit_encoding) + { + const xmlChar *encoding; + + /* default encoding is UTF-16 */ + XSLT_GET_IMPORT_PTR(encoding, style, encoding); + xmlOutputBufferWriteString(output, " encoding="); + xmlOutputBufferWriteString(output, "\""); + xmlOutputBufferWriteString(output, encoding ? (const char *)encoding : "UTF-16"); + xmlOutputBufferWriteString(output, "\""); + } + + /* standalone attribute */ + if (standalone != -1) + xmlOutputBufferWriteString(output, standalone == 0 ? " standalone=\"no\"" : " standalone=\"yes\""); + + xmlOutputBufferWriteString(output, "?>"); +} + +static void htmldtd_dumpcontent(xmlOutputBufferPtr buf, xmlDocPtr doc) +{ + xmlDtdPtr cur = doc->intSubset; + + xmlOutputBufferWriteString(buf, "<!DOCTYPE "); + xmlOutputBufferWriteString(buf, (const char *)cur->name); + if (cur->ExternalID) + { + xmlOutputBufferWriteString(buf, " PUBLIC "); + xml_write_quotedstring(buf, cur->ExternalID); + if (cur->SystemID) + { + xmlOutputBufferWriteString(buf, " "); + xml_write_quotedstring(buf, cur->SystemID); + } + } + else if (cur->SystemID) + { + xmlOutputBufferWriteString(buf, " SYSTEM "); + xml_write_quotedstring(buf, cur->SystemID); + } + xmlOutputBufferWriteString(buf, ">\n"); +} + +/* Duplicates htmlDocContentDumpFormatOutput() the way we need it - doesn't add trailing newline. */ +static void htmldoc_dumpcontent(xmlOutputBufferPtr buf, xmlDocPtr doc, const char *encoding, int format) +{ + xmlElementType type; + + /* force HTML output */ + type = doc->type; + doc->type = XML_HTML_DOCUMENT_NODE; + if (doc->intSubset) + htmldtd_dumpcontent(buf, doc); + if (doc->children) { + xmlNodePtr cur = doc->children; + while (cur) { + htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format); + cur = cur->next; + } + } + doc->type = type; +} + +static inline BOOL transform_is_empty_resultdoc(xmlDocPtr result) +{ + return !result->children || ((result->children->type == XML_DTD_NODE) && !result->children->next); +} + +static inline BOOL transform_is_valid_method(xsltStylesheetPtr style) +{ + return !style->methodURI || !(style->method && xmlStrEqual(style->method, (const xmlChar *)"xhtml")); +} + +/* Helper to write transformation result to specified output buffer. */ +static HRESULT node_transform_write(xsltStylesheetPtr style, xmlDocPtr result, BOOL omit_encoding, const char *encoding, xmlOutputBufferPtr output) +{ + const xmlChar *method; + int indent; + + if (!transform_is_valid_method(style)) + { + ERR("unknown output method\n"); + return E_FAIL; + } + + XSLT_GET_IMPORT_PTR(method, style, method) + XSLT_GET_IMPORT_INT(indent, style, indent); + + if (!method && (result->type == XML_HTML_DOCUMENT_NODE)) + method = (const xmlChar *) "html"; + + if (method && xmlStrEqual(method, (const xmlChar *)"html")) + { + htmlSetMetaEncoding(result, (const xmlChar *)encoding); + if (indent == -1) + indent = 1; + htmldoc_dumpcontent(output, result, encoding, indent); + } + else if (method && xmlStrEqual(method, (const xmlChar *)"xhtml")) + { + htmlSetMetaEncoding(result, (const xmlChar *) encoding); + htmlDocContentDumpOutput(output, result, encoding); + } + else if (method && xmlStrEqual(method, (const xmlChar *)"text")) + transform_write_text(result, style, output); + else + { + transform_write_xmldecl(result, style, omit_encoding, output); + + if (result->children) + { + xmlNodePtr child = result->children; + + while (child) + { + xmlNodeDumpOutput(output, result, child, 0, indent == 1, encoding); + if (indent && ((child->type == XML_DTD_NODE) || ((child->type == XML_COMMENT_NODE) && child->next))) + xmlOutputBufferWriteString(output, "\r\n"); + child = child->next; + } + } + } + + xmlOutputBufferFlush(output); + return S_OK; +} + +/* For BSTR output is always UTF-16, without 'encoding' attribute */ +static HRESULT node_transform_write_to_bstr(xsltStylesheetPtr style, xmlDocPtr result, BSTR *str) +{ + HRESULT hr = S_OK; + + if (transform_is_empty_resultdoc(result)) + *str = SysAllocStringLen(NULL, 0); + else + { + xmlOutputBufferPtr output = xmlAllocOutputBuffer(xmlFindCharEncodingHandler("UTF-16")); + const xmlChar *content; + size_t len; + + *str = NULL; + if (!output) + return E_OUTOFMEMORY; + + hr = node_transform_write(style, result, TRUE, "UTF-16", output); + content = xmlBufContent(output->conv); + len = xmlBufUse(output->conv); + /* UTF-16 encoder places UTF-16 bom, we don't need it for BSTR */ + content += sizeof(WCHAR); + *str = SysAllocStringLen((WCHAR*)content, len/sizeof(WCHAR) - 1); + xmlOutputBufferClose(output); + } + + return *str ? hr : E_OUTOFMEMORY; +} + +static HRESULT node_transform_write_to_stream(xsltStylesheetPtr style, xmlDocPtr result, ISequentialStream *stream) +{ + static const xmlChar *utf16 = (const xmlChar*)"UTF-16"; + xmlOutputBufferPtr output; + const xmlChar *encoding; + HRESULT hr; + + if (transform_is_empty_resultdoc(result)) + { + WARN("empty result document\n"); + return S_OK; + } + + if (style->methodURI && (!style->method || !xmlStrEqual(style->method, (const xmlChar *) "xhtml"))) + { + ERR("unknown output method\n"); + return E_FAIL; + } + + /* default encoding is UTF-16 */ + XSLT_GET_IMPORT_PTR(encoding, style, encoding); + if (!encoding) + encoding = utf16; + + output = xmlOutputBufferCreateIO(transform_to_stream_write, NULL, stream, xmlFindCharEncodingHandler((const char*)encoding)); + if (!output) + return E_OUTOFMEMORY; + + hr = node_transform_write(style, result, FALSE, (const char*)encoding, output); + xmlOutputBufferClose(output); + return hr; +} + +struct import_buffer +{ + char *data; + int cur; + int len; +}; + +static int XMLCALL import_loader_io_read(void *context, char *out, int len) +{ + struct import_buffer *buffer = (struct import_buffer *)context; + + TRACE("%p, %p, %d\n", context, out, len); + + if (buffer->cur == buffer->len) + return 0; + + len = min(len, buffer->len - buffer->cur); + memcpy(out, &buffer->data[buffer->cur], len); + buffer->cur += len; + + TRACE("read %d\n", len); + + return len; +} + +static int XMLCALL import_loader_io_close(void * context) +{ + struct import_buffer *buffer = (struct import_buffer *)context; + + TRACE("%p\n", context); + + free(buffer->data); + free(buffer); + return 0; +} + +static HRESULT import_loader_onDataAvailable(void *ctxt, char *ptr, DWORD len) +{ + xmlParserInputPtr *input = (xmlParserInputPtr *)ctxt; + xmlParserInputBufferPtr inputbuffer; + struct import_buffer *buffer; + + buffer = malloc(sizeof(*buffer)); + + buffer->data = malloc(len); + memcpy(buffer->data, ptr, len); + buffer->cur = 0; + buffer->len = len; + + inputbuffer = xmlParserInputBufferCreateIO(import_loader_io_read, import_loader_io_close, buffer, + XML_CHAR_ENCODING_NONE); + *input = xmlNewIOInputStream(NULL, inputbuffer, XML_CHAR_ENCODING_NONE); + if (!*input) + xmlFreeParserInputBuffer(inputbuffer); + + return *input ? S_OK : E_FAIL; +} + +static HRESULT xslt_doc_get_uri(const xmlChar *uri, void *_ctxt, xsltLoadType type, IUri **doc_uri) +{ + xsltStylesheetPtr style = (xsltStylesheetPtr)_ctxt; + IUri *href_uri; + HRESULT hr; + BSTR uriW; + + *doc_uri = NULL; + + uriW = bstr_from_xmlChar(uri); + hr = CreateUri(uriW, Uri_CREATE_ALLOW_RELATIVE | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &href_uri); + SysFreeString(uriW); + if (FAILED(hr)) + { + WARN("Failed to create href uri, %#lx.\n", hr); + return hr; + } + + if (type == XSLT_LOAD_STYLESHEET && style->doc && style->doc->name) + { + IUri *base_uri; + BSTR baseuriW; + + baseuriW = bstr_from_xmlChar((xmlChar *)style->doc->name); + hr = CreateUri(baseuriW, Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &base_uri); + SysFreeString(baseuriW); + if (FAILED(hr)) + { + WARN("Failed to create base uri, %#lx.\n", hr); + return hr; + } + + hr = CoInternetCombineIUri(base_uri, href_uri, 0, doc_uri, 0); + IUri_Release(base_uri); + if (FAILED(hr)) + WARN("Failed to combine uris, hr %#lx.\n", hr); + } + else + { + *doc_uri = href_uri; + IUri_AddRef(*doc_uri); + } + + IUri_Release(href_uri); + + return hr; +} + +xmlDocPtr xslt_doc_default_loader(const xmlChar *uri, xmlDictPtr dict, int options, + void *_ctxt, xsltLoadType type) +{ + IUri *import_uri = NULL; + xmlParserInputPtr input; + xmlParserCtxtPtr pctxt; + xmlDocPtr doc = NULL; + IMoniker *moniker; + HRESULT hr; + bsc_t *bsc; + BSTR uriW; + + TRACE("%s, %p, %#x, %p, %d\n", debugstr_a((const char *)uri), dict, options, _ctxt, type); + + pctxt = xmlNewParserCtxt(); + if (!pctxt) + return NULL; + + if (dict && pctxt->dict) + { + xmlDictFree(pctxt->dict); + pctxt->dict = NULL; + } + + if (dict) + { + pctxt->dict = dict; + xmlDictReference(pctxt->dict); + } + + xmlCtxtUseOptions(pctxt, options); + + hr = xslt_doc_get_uri(uri, _ctxt, type, &import_uri); + if (FAILED(hr)) + goto failed; + + hr = CreateURLMonikerEx2(NULL, import_uri, &moniker, 0); + if (FAILED(hr)) + goto failed; + + hr = bind_url(moniker, import_loader_onDataAvailable, &input, &bsc); + IMoniker_Release(moniker); + if (FAILED(hr)) + goto failed; + + if (FAILED(detach_bsc(bsc))) + goto failed; + + if (!input) + goto failed; + + inputPush(pctxt, input); + xmlParseDocument(pctxt); + + if (pctxt->wellFormed) + { + doc = pctxt->myDoc; + /* Set imported uri, to give nested imports a chance. */ + if (IUri_GetPropertyBSTR(import_uri, Uri_PROPERTY_ABSOLUTE_URI, &uriW, 0) == S_OK) + { + doc->name = (char *)xmlchar_from_wcharn(uriW, SysStringLen(uriW), TRUE); + SysFreeString(uriW); + } + } + else + { + doc = NULL; + xmlFreeDoc(pctxt->myDoc); + pctxt->myDoc = NULL; + } + +failed: + xmlFreeParserCtxt(pctxt); + if (import_uri) + IUri_Release(import_uri); + + return doc; +} + +#ifdef _WIN64 + +#define IActiveScriptParse_Release IActiveScriptParse64_Release +#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew +#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText + +#else + +#define IActiveScriptParse_Release IActiveScriptParse32_Release +#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew +#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText + +#endif + +struct xsl_scripts +{ + struct + { + IActiveScript *script; + const xmlChar *uri; + } *entries; + size_t count; + size_t capacity; +}; + +static IActiveScript *xpath_msxsl_script_get_script(xmlXPathParserContextPtr ctxt, const xmlChar *uri) +{ + xsltTransformContextPtr xslt_ctxt = xsltXPathGetTransformContext(ctxt); + struct xsl_scripts *scripts = xslt_ctxt->userData; + + for (size_t i = 0; i < scripts->count; ++i) + { + if (xmlStrEqual(scripts->entries[i].uri, uri)) + return scripts->entries[i].script; + } + + return NULL; +} + +static HRESULT xpath_create_nodelist_from_set(xmlNodeSetPtr set, bool needs_copy, IXMLDOMNodeList **ret) +{ + xmlNodeSet _copy = { 0 }; + xmlXPathObjectPtr obj; + HRESULT hr; + + if (needs_copy) + { + _copy.nodeTab = xmlMalloc(set->nodeNr * sizeof(*set->nodeTab)); + _copy.nodeNr = set->nodeNr; + _copy.nodeMax = set->nodeNr; + for (int i = 0; i < set->nodeNr; ++i) + _copy.nodeTab[i] = xmlCopyNode(set->nodeTab[i], 1); + set = &_copy; + } + + obj = xmlXPathNewNodeSetList(set); + hr = create_selection_from_nodeset(obj, ret); + xmlFree(_copy.nodeTab); + + return hr; +} + +static void xpath_msxsl_script_function(xmlXPathParserContextPtr ctxt, int nargs) +{ + xsltTransformContextPtr xslt_ctxt = xsltXPathGetTransformContext(ctxt); + xmlXPathContextPtr xpath = ((struct _xsltTransformContext *)xslt_ctxt)->xpathCtxt; + DISPPARAMS params = { 0 }; + IActiveScript *script; + VARIANT *args = NULL; + IDispatch *disp; + VARIANT result; + DISPID dispid; + HRESULT hr; + BSTR name; + + TRACE("%s:%s\n", xpath->functionURI, xpath->function); + + script = xpath_msxsl_script_get_script(ctxt, xpath->functionURI); + if (!script) + { + WARN("Couldn't find a script for %s.\n", xpath->functionURI); + return; + } + + if (FAILED(IActiveScript_GetScriptDispatch(script, NULL, &disp))) + return; + + name = bstr_from_xmlChar(xpath->function); + hr = IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, &dispid); + SysFreeString(name); + if (FAILED(hr)) + { + WARN("Couldn't find %s function.\n", xpath->function); + IDispatch_Release(disp); + return; + } + + if (nargs) + { + args = calloc(nargs, sizeof(*args)); + + for (int i = 0; i < nargs; ++i) + { + xmlXPathObjectType obj_type = XPATH_UNDEFINED; + xmlXPathObjectPtr obj = NULL; + xmlChar *s; + + /* Since we don't want to impose expectations on argument types, + first inspect actual type on stack, and then pop with corresponding function. */ + if (ctxt->valueNr > 0) + { + obj = ctxt->valueTab[ctxt->valueNr - 1]; + obj_type = obj->type; + } + + switch (obj_type) + { + case XPATH_XSLT_TREE: + case XPATH_NODESET: + { + xmlNodeSetPtr nodeset = xmlXPathPopNodeSet(ctxt); + IXMLDOMNodeList *nodelist; + + hr = xpath_create_nodelist_from_set(nodeset, obj_type == XPATH_XSLT_TREE, &nodelist); + + V_VT(&args[i]) = VT_DISPATCH; + V_DISPATCH(&args[i]) = (IDispatch *)nodelist; + break; + } + case XPATH_STRING: + s = xmlXPathPopString(ctxt); + V_VT(&args[i]) = VT_BSTR; + V_BSTR(&args[i]) = bstr_from_xmlChar(s); + xmlFree(s); + break; + case XPATH_NUMBER: + V_VT(&args[i]) = VT_R8; + V_R8(&args[i]) = xmlXPathPopNumber(ctxt); + break; + case XPATH_BOOLEAN: + V_VT(&args[i]) = VT_BOOL; + V_BOOL(&args[i]) = xmlXPathPopBoolean(ctxt) ? VARIANT_TRUE : VARIANT_FALSE; + break; + default: + FIXME("Unexpected XPath (%s) value type %d.\n", xpath->function, obj->type); + return; + } + } + + params.rgvarg = args; + params.cArgs = nargs; + } + + VariantInit(&result); + hr = IDispatch_Invoke(disp, dispid, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, &result, NULL, NULL); + if (FAILED(hr)) + WARN("User script Invoke() failed %#lx, function %s.\n", hr, xpath->function); + + if (args) + { + for (int i = 0; i < nargs; ++i) + VariantClear(&args[i]); + free(args); + } + + switch (V_VT(&result)) + { + case VT_BSTR: + { + xmlChar *s = xmlchar_from_wcharn(V_BSTR(&result), -1, TRUE); + xmlXPathReturnString(ctxt, s); + break; + } + case VT_BOOL: + xmlXPathReturnBoolean(ctxt, !!V_BOOL(&result)); + break; + case VT_INT: + case VT_I1: + case VT_UI1: + case VT_I2: + case VT_UI2: + case VT_I4: + case VT_UI4: + case VT_R4: + case VT_R8: + VariantChangeType(&result, &result, 0, VT_R8); + xmlXPathReturnNumber(ctxt, V_R8(&result)); + break; + case VT_EMPTY: + xmlXPathReturnEmptyString(ctxt); + break; + default: + FIXME("Unexpected return value %s.\n", debugstr_variant(&result)); + xmlXPathReturnEmptyString(ctxt); + } + + IDispatch_Release(disp); + VariantClear(&result); +} + +struct msxsl_script_site +{ + IActiveScriptSite IActiveScriptSite_iface; + IServiceProvider IServiceProvider_iface; + LONG refcount; + + IServiceProvider *provider; +}; + +static struct msxsl_script_site *impl_from_IActiveScriptSite(IActiveScriptSite *iface) +{ + return CONTAINING_RECORD(iface, struct msxsl_script_site, IActiveScriptSite_iface); +} + +static struct msxsl_script_site *impl_from_IServiceProvider(IServiceProvider *iface) +{ + return CONTAINING_RECORD(iface, struct msxsl_script_site, IServiceProvider_iface); +} + +static HRESULT WINAPI msxsl_script_site_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **obj) +{ + struct msxsl_script_site *site = impl_from_IActiveScriptSite(iface); + + if (IsEqualGUID(&IID_IUnknown, riid) + || IsEqualGUID(&IID_IActiveScriptSite, riid)) + { + *obj = iface; + IActiveScriptSite_AddRef(iface); + return S_OK; + } + else if (IsEqualGUID(&IID_IServiceProvider, riid)) + { + *obj = &site->IServiceProvider_iface; + IServiceProvider_AddRef(&site->IServiceProvider_iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI msxsl_script_site_AddRef(IActiveScriptSite *iface) +{ + struct msxsl_script_site *site = impl_from_IActiveScriptSite(iface); + return InterlockedIncrement(&site->refcount); +} + +static ULONG WINAPI msxsl_script_site_Release(IActiveScriptSite *iface) +{ + struct msxsl_script_site *site = impl_from_IActiveScriptSite(iface); + LONG refcount = InterlockedDecrement(&site->refcount); + + if (!refcount) + { + if (site->provider) + IServiceProvider_Release(site->provider); + free(site); + } + + return refcount; +} + +static HRESULT WINAPI msxsl_script_site_GetLCID(IActiveScriptSite *iface, LCID *lcid) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI msxsl_script_site_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR name, + DWORD mask, IUnknown **item, ITypeInfo **typeinfo) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI msxsl_script_site_GetDocVersionString(IActiveScriptSite *iface, BSTR *version) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI msxsl_script_site_OnScriptTerminate(IActiveScriptSite *iface, + const VARIANT *result, const EXCEPINFO *ei) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI msxsl_script_site_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE state) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI msxsl_script_site_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *script_error) +{ + return S_OK; +} + +static HRESULT WINAPI msxsl_script_site_OnEnterScript(IActiveScriptSite *iface) +{ + return S_OK; +} + +static HRESULT WINAPI msxsl_script_site_OnLeaveScript(IActiveScriptSite *iface) +{ + return S_OK; +} + +static const IActiveScriptSiteVtbl msxsl_script_site_vtbl = +{ + msxsl_script_site_QueryInterface, + msxsl_script_site_AddRef, + msxsl_script_site_Release, + msxsl_script_site_GetLCID, + msxsl_script_site_GetItemInfo, + msxsl_script_site_GetDocVersionString, + msxsl_script_site_OnScriptTerminate, + msxsl_script_site_OnStateChange, + msxsl_script_site_OnScriptError, + msxsl_script_site_OnEnterScript, + msxsl_script_site_OnLeaveScript +}; + +static HRESULT WINAPI msxsl_script_site_servprov_QueryInterface(IServiceProvider *iface, REFIID riid, void **obj) +{ + struct msxsl_script_site *site = impl_from_IServiceProvider(iface); + return IActiveScriptSite_QueryInterface(&site->IActiveScriptSite_iface, riid, obj); +} + +static ULONG WINAPI msxsl_script_site_servprov_AddRef(IServiceProvider *iface) +{ + struct msxsl_script_site *site = impl_from_IServiceProvider(iface); + return IActiveScriptSite_AddRef(&site->IActiveScriptSite_iface); +} + +static ULONG WINAPI msxsl_script_site_servprov_Release(IServiceProvider *iface) +{ + struct msxsl_script_site *site = impl_from_IServiceProvider(iface); + return IActiveScriptSite_Release(&site->IActiveScriptSite_iface); +} + +static HRESULT WINAPI msxsl_script_site_servprov_QueryService(IServiceProvider *iface, + REFGUID service, REFIID riid, void **obj) +{ + struct msxsl_script_site *site = impl_from_IServiceProvider(iface); + + if (site->provider) + return IServiceProvider_QueryService(site->provider, service, riid, obj); + + *obj = NULL; + return E_NOINTERFACE; +} + +static const IServiceProviderVtbl msxsl_script_site_servprov_vtbl = +{ + msxsl_script_site_servprov_QueryInterface, + msxsl_script_site_servprov_AddRef, + msxsl_script_site_servprov_Release, + msxsl_script_site_servprov_QueryService, +}; + +static HRESULT msxsl_create_script_site(IXMLDOMDocument *doc, IActiveScriptSite **obj) +{ + struct msxsl_script_site *object; + IServiceProvider *provider = NULL; + IObjectWithSite *ows; + HRESULT hr; + + if (FAILED(hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectWithSite, (void **)&ows))) + return hr; + + IObjectWithSite_GetSite(ows, &IID_IServiceProvider, (void **)&provider); + IObjectWithSite_Release(ows); + + object = calloc(1, sizeof(*object)); + object->IActiveScriptSite_iface.lpVtbl = &msxsl_script_site_vtbl; + object->IServiceProvider_iface.lpVtbl = &msxsl_script_site_servprov_vtbl; + object->refcount = 1; + object->provider = provider; + + *obj = &object->IActiveScriptSite_iface; + + return S_OK; +} + +static void node_transform_bind_scripts(xsltTransformContextPtr ctxt, IXMLDOMDocument *owner_doc, + xmlDocPtr sheet, struct xsl_scripts *scripts) +{ + IActiveScriptSite *script_site; + xmlNodePtr root, child, node; + DWORD supported, enabled = 0; + IObjectSafety *object_safety; + xmlNsPtr ns; + + IXMLDOMDocument_QueryInterface(owner_doc, &IID_IObjectSafety, (void **)&object_safety); + IObjectSafety_GetInterfaceSafetyOptions(object_safety, NULL, &supported, &enabled); + IObjectSafety_Release(object_safety); + + if (FAILED(msxsl_create_script_site(owner_doc, &script_site))) + return; + + root = xmlDocGetRootElement(sheet); + for (node = root->children; node; node = node->next) + { + if (xmlStrEqual(node->name, BAD_CAST "script") + && node->ns + && xmlStrEqual(node->ns->prefix, BAD_CAST "msxsl") + && xmlStrEqual(node->ns->href, BAD_CAST "urn:schemas-microsoft-com:xslt")) + { + child = node->children; + + if (child && child->type == XML_CDATA_SECTION_NODE) + { + IActiveScript *active_script; + xmlChar *language, *prefix; + IActiveScriptParse *parser; + TYPEATTR *typeattr; + BSTR text, progid; + IDispatch *disp; + ITypeInfo *ti; + CLSID clsid; + HRESULT hr; + + if (!(prefix = xmlGetProp(node, BAD_CAST "implements-prefix"))) + { + WARN("<msxsl:script> without 'implements-prefix'.\n"); + continue; + } + + if (!(ns = xmlSearchNs(sheet, node, prefix))) + { + WARN("Couldn't locate script element namespace for \"%s\".\n", debugstr_a((char *)prefix)); + continue; + } + + if (!(language = xmlGetProp(node, BAD_CAST "language"))) + language = BAD_CAST "javascript"; + + progid = bstr_from_xmlChar(language); + if (FAILED(hr = CLSIDFromProgID(progid, &clsid))) + WARN("Unknown engine progid %s.\n", debugstr_w(progid)); + SysFreeString(progid); + if (FAILED(hr)) + return; + + if (FAILED(hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, + &IID_IActiveScript, (void **)&active_script))) + { + WARN("Failed to create a script engine instance, hr %#lx.\n", hr); + continue; + } + + IActiveScript_QueryInterface(active_script, &IID_IObjectSafety, (void **)&object_safety); + IObjectSafety_SetInterfaceSafetyOptions(object_safety, NULL, enabled, enabled); + IObjectSafety_Release(object_safety); + + IActiveScript_QueryInterface(active_script, &IID_IActiveScriptParse, (void **)&parser); + IActiveScript_SetScriptSite(active_script, script_site); + IActiveScriptParse_InitNew(parser); + IActiveScript_SetScriptState(active_script, SCRIPTSTATE_STARTED); + + text = bstr_from_xmlChar(child->content); + hr = IActiveScriptParse_ParseScriptText(parser, text, NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + IActiveScriptParse_Release(parser); + SysFreeString(text); + if (FAILED(hr)) + { + WARN("Failed to parse script for the namespace %s, hr %#lx.\n", prefix, hr); + IActiveScript_Release(active_script); + continue; + } + + IActiveScript_GetScriptDispatch(active_script, NULL, &disp); + IDispatch_GetTypeInfo(disp, 0, LOCALE_USER_DEFAULT, &ti); + + ITypeInfo_GetTypeAttr(ti, &typeattr); + + for (int i = 0; i < typeattr->cFuncs; ++i) + { + FUNCDESC *funcdesc; + xmlChar *func_name; + BSTR name; + + ITypeInfo_GetFuncDesc(ti, i, &funcdesc); + ITypeInfo_GetDocumentation(ti, funcdesc->memid, &name, NULL, NULL, NULL); + func_name = xmlchar_from_wchar(name); + + xsltRegisterExtFunction(ctxt, func_name, ns->href, xpath_msxsl_script_function); + + SysFreeString(name); + free(func_name); + } + + IDispatch_Release(disp); + ITypeInfo_Release(ti); + + array_reserve((void **)&scripts->entries, &scripts->capacity, scripts->count + 1, sizeof(*scripts->entries)); + + scripts->entries[scripts->count].script = active_script; + scripts->entries[scripts->count].uri = ns->href; + scripts->count++; + } + } + } + + IActiveScriptSite_Release(script_site); +} + +HRESULT node_transform_node_params(struct domnode *node, IXMLDOMNode *stylesheet, BSTR *p, + ISequentialStream *stream, const struct xslprocessor_params *params) +{ + xmlDocPtr sheet_doc, node_doc; + struct domnode *sheet_domdoc; + IXMLDOMDocument *owner_doc; + xsltStylesheetPtr xsltSS; + xmlNodePtr xmlnode; + HRESULT hr = S_OK; + + if (!stylesheet || (!p && !stream)) + return E_INVALIDARG; + + if (p) *p = NULL; + + if (FAILED(IXMLDOMNode_QueryInterface(stylesheet, &IID_IXMLDOMDocument, (void **)&owner_doc))) + { + if (FAILED(hr = IXMLDOMNode_get_ownerDocument(stylesheet, &owner_doc))) + return hr; + } + + sheet_domdoc = get_node_obj(owner_doc); + if (!sheet_domdoc) + { + IXMLDOMDocument_Release(owner_doc); + return E_FAIL; + } + + sheet_doc = create_xmldoc_from_domdoc(sheet_domdoc, &xmlnode); + node_doc = create_xmldoc_from_domdoc(node, &xmlnode); + + xsltSS = xsltParseStylesheetDoc(sheet_doc); + if (xsltSS) + { + struct xsl_scripts scripts = { 0 }; + const char **xslparams = NULL; + xsltTransformContextPtr ctxt; + xmlDocPtr result; + unsigned int i; + + /* convert our parameter list to libxml2 format */ + if (params && params->count) + { + struct xslprocessor_par *par; + + i = 0; + xslparams = malloc((params->count * 2 + 1) * sizeof(char*)); + LIST_FOR_EACH_ENTRY(par, ¶ms->list, struct xslprocessor_par, entry) + { + xslparams[i++] = (char*)xmlchar_from_wchar(par->name); + xslparams[i++] = (char*)xmlchar_from_wchar(par->value); + } + xslparams[i] = NULL; + } + + ctxt = xsltNewTransformContext(xsltSS, node_doc); + + node_transform_bind_scripts(ctxt, owner_doc, sheet_doc, &scripts); + ctxt->userData = &scripts; + + if (xslparams) + { + /* push parameters to user context */ + xsltQuoteUserParams(ctxt, xslparams); + result = xsltApplyStylesheetUser(xsltSS, node_doc, NULL, NULL, NULL, ctxt); + + for (i = 0; i < params->count*2; i++) + free((char*)xslparams[i]); + free(xslparams); + } + else + { + result = xsltApplyStylesheetUser(xsltSS, node_doc, NULL, NULL, NULL, ctxt); + } + + for (size_t i = 0; i < scripts.count; ++i) + { + if (scripts.entries[i].script) + IActiveScript_Release(scripts.entries[i].script); + } + free(scripts.entries); + + ctxt->userData = NULL; + xsltFreeTransformContext(ctxt); + + if (result) + { + if (stream) + hr = node_transform_write_to_stream(xsltSS, result, stream); + else + hr = node_transform_write_to_bstr(xsltSS, result, p); + xmlFreeDoc(result); + } + + xsltFreeStylesheet(xsltSS); } + else + xmlFreeDoc(sheet_doc); - IDispatch_Release(disp); - VariantClear(&result); -} + xmlFreeDoc(node_doc); -struct msxsl_script_site -{ - IActiveScriptSite IActiveScriptSite_iface; - IServiceProvider IServiceProvider_iface; - LONG refcount; + if (p && !*p) *p = SysAllocStringLen(NULL, 0); - IServiceProvider *provider; -}; + IXMLDOMDocument_Release(owner_doc); -static struct msxsl_script_site *impl_from_IActiveScriptSite(IActiveScriptSite *iface) + return hr; +} + +HRESULT node_transform_node(struct domnode *node, IXMLDOMNode *stylesheet, BSTR *p) { - return CONTAINING_RECORD(iface, struct msxsl_script_site, IActiveScriptSite_iface); + return node_transform_node_params(node, stylesheet, p, NULL, NULL); } -static struct msxsl_script_site *impl_from_IServiceProvider(IServiceProvider *iface) +HRESULT node_select_nodes(struct domnode *node, BSTR query, IXMLDOMNodeList **list) { - return CONTAINING_RECORD(iface, struct msxsl_script_site, IServiceProvider_iface); + struct domnode *doc = node_get_doc(node); + + if (!query || !list) + return E_INVALIDARG; + + return create_selection(node, query, doc->properties->XPath, list); } -static HRESULT WINAPI msxsl_script_site_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **obj) +HRESULT node_select_singlenode(struct domnode *node, BSTR query, IXMLDOMNode **ret) { - struct msxsl_script_site *site = impl_from_IActiveScriptSite(iface); + IXMLDOMNodeList *list; + HRESULT hr; - if (IsEqualGUID(&IID_IUnknown, riid) - || IsEqualGUID(&IID_IActiveScriptSite, riid)) - { - *obj = iface; - IActiveScriptSite_AddRef(iface); - return S_OK; - } - else if (IsEqualGUID(&IID_IServiceProvider, riid)) + if (ret) + *ret = NULL; + + hr = node_select_nodes(node, query, &list); + if (hr == S_OK) { - *obj = &site->IServiceProvider_iface; - IServiceProvider_AddRef(&site->IServiceProvider_iface); - return S_OK; + hr = IXMLDOMNodeList_nextNode(list, ret); + IXMLDOMNodeList_Release(list); } - - *obj = NULL; - return E_NOINTERFACE; + return hr; } -static ULONG WINAPI msxsl_script_site_AddRef(IActiveScriptSite *iface) +HRESULT node_get_namespaceURI(struct domnode *node, BSTR *uri) { - struct msxsl_script_site *site = impl_from_IActiveScriptSite(iface); - return InterlockedIncrement(&site->refcount); + if (!uri) + return E_INVALIDARG; + + *uri = NULL; + + return node->uri ? return_bstr(node->uri, uri) : S_FALSE; } -static ULONG WINAPI msxsl_script_site_Release(IActiveScriptSite *iface) +HRESULT node_attribute_get_namespace_uri(struct domnode *node, BSTR *uri) { - struct msxsl_script_site *site = impl_from_IActiveScriptSite(iface); - LONG refcount = InterlockedDecrement(&site->refcount); + struct domnode *doc = node->owner; + bool version6, defaultns; - if (!refcount) + if (!uri) + return E_INVALIDARG; + + *uri = NULL; + + version6 = doc->properties->version == MSXML6; + defaultns = !wcscmp(node->qname, L"xmlns"); + + if (defaultns || is_same_namespace_prefix(node, L"xmlns")) { - if (site->provider) - IServiceProvider_Release(site->provider); - free(site); + if (version6) + *uri = SysAllocString(L"http://www.w3.org/2000/xmlns/"); + else if (!node->uri || !defaultns) + *uri = SysAllocStringLen(NULL, 0); + else + *uri = SysAllocString(L"xmlns"); + + return *uri ? S_OK : E_OUTOFMEMORY; } - return refcount; + return node_get_namespaceURI(node, uri); } -static HRESULT WINAPI msxsl_script_site_GetLCID(IActiveScriptSite *iface, LCID *lcid) +HRESULT node_get_prefix(struct domnode *node, BSTR *prefix) { - return E_NOTIMPL; -} + if (!prefix) + return E_INVALIDARG; -static HRESULT WINAPI msxsl_script_site_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR name, - DWORD mask, IUnknown **item, ITypeInfo **typeinfo) -{ - return E_NOTIMPL; -} + *prefix = NULL; -static HRESULT WINAPI msxsl_script_site_GetDocVersionString(IActiveScriptSite *iface, BSTR *version) -{ - return E_NOTIMPL; + return node->prefix ? return_bstr(node->prefix, prefix) : S_FALSE; } -static HRESULT WINAPI msxsl_script_site_OnScriptTerminate(IActiveScriptSite *iface, - const VARIANT *result, const EXCEPINFO *ei) +HRESULT node_get_attribute(const struct domnode *node, const WCHAR *name, IXMLDOMAttribute **attribute) { - return E_NOTIMPL; -} + struct domnode *attr; + IUnknown *obj; + HRESULT hr; -static HRESULT WINAPI msxsl_script_site_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE state) -{ - return E_NOTIMPL; -} + if (attribute) + *attribute = NULL; -static HRESULT WINAPI msxsl_script_site_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *script_error) -{ - return S_OK; -} + if (!parser_is_valid_qualified_name(name)) + return E_FAIL; -static HRESULT WINAPI msxsl_script_site_OnEnterScript(IActiveScriptSite *iface) -{ - return S_OK; -} + if (!attribute) + return S_FALSE; -static HRESULT WINAPI msxsl_script_site_OnLeaveScript(IActiveScriptSite *iface) -{ - return S_OK; -} + if (domnode_get_attribute(node, name, &attr) != S_OK) + return S_FALSE; -static const IActiveScriptSiteVtbl msxsl_script_site_vtbl = -{ - msxsl_script_site_QueryInterface, - msxsl_script_site_AddRef, - msxsl_script_site_Release, - msxsl_script_site_GetLCID, - msxsl_script_site_GetItemInfo, - msxsl_script_site_GetDocVersionString, - msxsl_script_site_OnScriptTerminate, - msxsl_script_site_OnStateChange, - msxsl_script_site_OnScriptError, - msxsl_script_site_OnEnterScript, - msxsl_script_site_OnLeaveScript -}; + hr = create_attribute(attr, &obj); + if (SUCCEEDED(hr)) + { + hr = IUnknown_QueryInterface(obj, &IID_IXMLDOMAttribute, (void **)attribute); + IUnknown_Release(obj); + } -static HRESULT WINAPI msxsl_script_site_servprov_QueryInterface(IServiceProvider *iface, REFIID riid, void **obj) -{ - struct msxsl_script_site *site = impl_from_IServiceProvider(iface); - return IActiveScriptSite_QueryInterface(&site->IActiveScriptSite_iface, riid, obj); + return hr; } -static ULONG WINAPI msxsl_script_site_servprov_AddRef(IServiceProvider *iface) +HRESULT node_get_qualified_attribute(const struct domnode *node, const WCHAR *name, const WCHAR *uri, IXMLDOMNode **ret) { - struct msxsl_script_site *site = impl_from_IServiceProvider(iface); - return IActiveScriptSite_AddRef(&site->IActiveScriptSite_iface); + struct domnode *attr; + + if (!ret) + return S_FALSE; + + if (ret) + *ret = NULL; + + if (domnode_get_qualified_attribute(node, name, uri, &attr) != S_OK) + return S_FALSE; + + return create_node(attr, ret); } -static ULONG WINAPI msxsl_script_site_servprov_Release(IServiceProvider *iface) +HRESULT node_remove_qualified_attribute(struct domnode *node, const WCHAR *name, const WCHAR *uri, IXMLDOMNode **ret) { - struct msxsl_script_site *site = impl_from_IServiceProvider(iface); - return IActiveScriptSite_Release(&site->IActiveScriptSite_iface); + struct domnode *attr; + HRESULT hr; + + if (!name) + return E_INVALIDARG; + + if (ret) + *ret = NULL; + + if ((hr = domnode_get_qualified_attribute(node, name, uri, &attr)) != S_OK) + return hr; + + if (ret) + hr = create_node(attr, ret); + + if (SUCCEEDED(hr)) + domnode_unlink_attribute(attr); + + return hr; } -static HRESULT WINAPI msxsl_script_site_servprov_QueryService(IServiceProvider *iface, - REFGUID service, REFIID riid, void **obj) +HRESULT node_get_attribute_by_index(const struct domnode *node, LONG index, IXMLDOMNode **attr) { - struct msxsl_script_site *site = impl_from_IServiceProvider(iface); + struct domnode *n, *curr = NULL; - if (site->provider) - return IServiceProvider_QueryService(site->provider, service, riid, obj); + *attr = NULL; - *obj = NULL; - return E_NOINTERFACE; + if (index < 0) + return S_FALSE; + + LIST_FOR_EACH_ENTRY(n, &node->attributes, struct domnode, entry) + { + curr = n; + if (!index--) break; + curr = NULL; + } + + if (!curr) + return S_FALSE; + + return create_node(curr, attr); } -static const IServiceProviderVtbl msxsl_script_site_servprov_vtbl = +HRESULT node_get_attribute_value(struct domnode *node, const WCHAR *name, VARIANT *value) { - msxsl_script_site_servprov_QueryInterface, - msxsl_script_site_servprov_AddRef, - msxsl_script_site_servprov_Release, - msxsl_script_site_servprov_QueryService, -}; + struct domnode *attr, *child; + struct string_buffer buffer; -static HRESULT msxsl_create_script_site(IXMLDOMDocument *doc, IActiveScriptSite **obj) + if (!name || !value) + return E_INVALIDARG; + + VariantInit(value); + + if (!parser_is_valid_qualified_name(name)) + return E_FAIL; + + if (domnode_get_attribute(node, name, &attr) != S_OK) + { + V_VT(value) = VT_NULL; + return S_FALSE; + } + + string_buffer_init(&buffer); + LIST_FOR_EACH_ENTRY(child, &attr->children, struct domnode, entry) + { + string_append(&buffer, child->data, SysStringLen(child->data)); + } + + V_VT(value) = VT_BSTR; + return string_to_bstr(&buffer, &V_BSTR(value)); +} + +HRESULT node_set_attribute(struct domnode *node, IXMLDOMNode *attribute, IXMLDOMNode **ret) { - struct msxsl_script_site *object; - IServiceProvider *provider = NULL; - IObjectWithSite *ows; + struct domnode *attr, *old_attr; HRESULT hr; - if (FAILED(hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectWithSite, (void **)&ows))) - return hr; + if (!attribute) + return E_INVALIDARG; - IObjectWithSite_GetSite(ows, &IID_IServiceProvider, (void **)&provider); - IObjectWithSite_Release(ows); + if (!(attr = get_node_obj(attribute))) + return E_FAIL; - object = calloc(1, sizeof(*object)); - object->IActiveScriptSite_iface.lpVtbl = &msxsl_script_site_vtbl; - object->IServiceProvider_iface.lpVtbl = &msxsl_script_site_servprov_vtbl; - object->refcount = 1; - object->provider = provider; + if (attr->type != NODE_ATTRIBUTE) + return E_FAIL; - *obj = &object->IActiveScriptSite_iface; + if (attr->parent) + return E_FAIL; + + if (ret) + *ret = NULL; + + if (domnode_get_attribute(node, attr->qname, &old_attr) == S_OK) + { + if (ret) + { + if (FAILED(hr = create_node(old_attr, ret))) + return hr; + } + + list_add_before(&old_attr->entry, &attr->entry); + attr->parent = node; + + domnode_unlink_attribute(old_attr); + } + else + { + domnode_append_attribute(node, attr); + } return S_OK; } -static void node_transform_bind_scripts(xsltTransformContextPtr ctxt, IXMLDOMDocument *owner_doc, - xmlDocPtr sheet, struct xsl_scripts *scripts) +HRESULT node_set_attribute_value(struct domnode *node, const WCHAR *name, const VARIANT *value) { - IActiveScriptSite *script_site; - xmlNodePtr root, child, node; - DWORD supported, enabled = 0; - IObjectSafety *object_safety; - xmlNsPtr ns; - - IXMLDOMDocument_QueryInterface(owner_doc, &IID_IObjectSafety, (void **)&object_safety); - IObjectSafety_GetInterfaceSafetyOptions(object_safety, NULL, &supported, &enabled); - IObjectSafety_Release(object_safety); + struct parsed_name attr_name; + struct domnode *attr; + BSTR attr_value; + bool match; + HRESULT hr; + VARIANT v; - if (FAILED(msxsl_create_script_site(owner_doc, &script_site))) - return; + if (FAILED(parse_qualified_name(name, &attr_name))) + return E_FAIL; - root = xmlDocGetRootElement(sheet); - for (node = root->children; node; node = node->next) + if (FAILED(hr = variant_get_str_value(value, &v, &attr_value))) { - if (xmlStrEqual(node->name, BAD_CAST "script") - && node->ns - && xmlStrEqual(node->ns->prefix, BAD_CAST "msxsl") - && xmlStrEqual(node->ns->href, BAD_CAST "urn:schemas-microsoft-com:xslt")) - { - child = node->children; + parsed_name_cleanup(&attr_name); + return hr; + } - if (child && child->type == XML_CDATA_SECTION_NODE) - { - IActiveScript *active_script; - xmlChar *language, *prefix; - IActiveScriptParse *parser; - TYPEATTR *typeattr; - BSTR text, progid; - IDispatch *disp; - ITypeInfo *ti; - CLSID clsid; - HRESULT hr; + /* Check for conflict with element namespace */ + match = is_same_namespace_prefix(node, attr_name.local) && !is_same_uri(node, attr_value); + parsed_name_cleanup(&attr_name); + + if (match) + { + VariantClear(&v); + return E_INVALIDARG; + } - if (!(prefix = xmlGetProp(node, BAD_CAST "implements-prefix"))) - { - WARN("<msxsl:script> without 'implements-prefix'.\n"); - continue; - } + if (domnode_get_attribute(node, name, &attr) != S_OK) + { + if (SUCCEEDED(hr = domnode_create(NODE_ATTRIBUTE, name, wcslen(name), NULL, 0, node->owner, &attr))) + domnode_append_attribute(node, attr); + } - if (!(ns = xmlSearchNs(sheet, node, prefix))) - { - WARN("Couldn't locate script element namespace for \"%s\".\n", debugstr_a((char *)prefix)); - continue; - } + if (SUCCEEDED(hr)) + hr = node_put_data(attr, attr_value); + VariantClear(&v); - if (!(language = xmlGetProp(node, BAD_CAST "language"))) - language = BAD_CAST "javascript"; + return hr; +} - progid = bstr_from_xmlChar(language); - if (FAILED(hr = CLSIDFromProgID(progid, &clsid))) - WARN("Unknown engine progid %s.\n", debugstr_w(progid)); - SysFreeString(progid); - if (FAILED(hr)) - return; +HRESULT node_get_base_name(struct domnode *node, BSTR *name) +{ + return return_bstr(node->name, name); +} - if (FAILED(hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, - &IID_IActiveScript, (void **)&active_script))) - { - WARN("Failed to create a script engine instance, hr %#lx.\n", hr); - continue; - } +HRESULT create_node(struct domnode *node, IXMLDOMNode **ret) +{ + IUnknown *obj; + HRESULT hr; - IActiveScript_QueryInterface(active_script, &IID_IObjectSafety, (void **)&object_safety); - IObjectSafety_SetInterfaceSafetyOptions(object_safety, NULL, enabled, enabled); - IObjectSafety_Release(object_safety); + *ret = NULL; - IActiveScript_QueryInterface(active_script, &IID_IActiveScriptParse, (void **)&parser); - IActiveScript_SetScriptSite(active_script, script_site); - IActiveScriptParse_InitNew(parser); - IActiveScript_SetScriptState(active_script, SCRIPTSTATE_STARTED); + if (!node) + return S_FALSE; - text = bstr_from_xmlChar(child->content); - hr = IActiveScriptParse_ParseScriptText(parser, text, NULL, NULL, NULL, 0, 0, 0, NULL, NULL); - IActiveScriptParse_Release(parser); - SysFreeString(text); - if (FAILED(hr)) - { - WARN("Failed to parse script for the namespace %s, hr %#lx.\n", prefix, hr); - IActiveScript_Release(active_script); - continue; - } + switch (node->type) + { + case NODE_ELEMENT: + hr = create_element(node, &obj); + break; + case NODE_ATTRIBUTE: + hr = create_attribute(node, &obj); + break; + case NODE_TEXT: + hr = create_text(node, &obj); + break; + case NODE_CDATA_SECTION: + hr = create_cdata(node, &obj); + break; + case NODE_ENTITY_REFERENCE: + hr = create_entity_ref(node, &obj); + break; + case NODE_PROCESSING_INSTRUCTION: + hr = create_pi(node, &obj); + break; + case NODE_COMMENT: + hr = create_comment(node, &obj); + break; + case NODE_DOCUMENT: + hr = create_domdoc(node, &obj); + break; + case NODE_DOCUMENT_FRAGMENT: + hr = create_doc_fragment(node, &obj); + break; + case NODE_DOCUMENT_TYPE: + hr = create_doc_type(node, &obj); + break; + case NODE_ENTITY: + case NODE_NOTATION: + FIXME("Unsupported node type %d.\n", node->type); + return E_NOTIMPL; + default: + WARN("Invalid node type %d\n", node->type); + return E_FAIL; + } - IActiveScript_GetScriptDispatch(active_script, NULL, &disp); - IDispatch_GetTypeInfo(disp, 0, LOCALE_USER_DEFAULT, &ti); + if (hr == S_OK) + { + hr = IUnknown_QueryInterface(obj, &IID_IXMLDOMNode, (void **)ret); + IUnknown_Release(obj); + } - ITypeInfo_GetTypeAttr(ti, &typeattr); + return hr; +} - for (int i = 0; i < typeattr->cFuncs; ++i) - { - FUNCDESC *funcdesc; - xmlChar *func_name; - BSTR name; +struct parse_context +{ + ISAXExtensionHandler extension_handler; + ISAXContentHandler content_handler; + ISAXLexicalHandler lexical_handler; + ISAXXMLReaderExtension *reader_extension; + ISAXXMLReader *reader; - ITypeInfo_GetFuncDesc(ti, i, &funcdesc); - ITypeInfo_GetDocumentation(ti, funcdesc->memid, &name, NULL, NULL, NULL); - func_name = xmlchar_from_wchar(name); + struct domnode *node; - xsltRegisterExtFunction(ctxt, func_name, ns->href, xpath_msxsl_script_function); + struct string_buffer buffer; - SysFreeString(name); - free(func_name); - } + /* Parsed output */ + struct domnode *root; - IDispatch_Release(disp); - ITypeInfo_Release(ti); + HRESULT status; +}; - array_reserve((void **)&scripts->entries, &scripts->capacity, scripts->count + 1, sizeof(*scripts->entries)); +static void parse_context_node_create(struct parse_context *context, DOMNodeType type, + const WCHAR *name, int name_len, const WCHAR *uri, int uri_len, struct domnode *owner, + struct domnode **node) +{ + *node = NULL; - scripts->entries[scripts->count].script = active_script; - scripts->entries[scripts->count].uri = ns->href; - scripts->count++; - } - } - } + if (context->status != S_OK) + return; - IActiveScriptSite_Release(script_site); + context->status = domnode_create(type, name, name_len, uri, uri_len, owner, node); } -HRESULT node_transform_node_params(const xmlnode *This, IXMLDOMNode *stylesheet, BSTR *p, - ISequentialStream *stream, const struct xslprocessor_params *params) +static void parse_context_append_child(struct parse_context *context, struct domnode *parent, struct domnode *child) { - IXMLDOMDocument *owner_doc; - xsltStylesheetPtr xsltSS; - xmlDocPtr sheet_doc; - HRESULT hr = S_OK; - xmlnode *sheet; + if (context->status == S_OK) + domnode_append_child(parent, child); +} - if (!stylesheet || (!p && !stream)) return E_INVALIDARG; +static void parse_context_append_attribute(struct parse_context *context, struct domnode *node, struct domnode *attribute) +{ + if (context->status == S_OK) + domnode_append_attribute(node, attribute); +} - if (p) *p = NULL; +static void parse_context_node_put_data(struct parse_context *context, struct domnode *node, const WCHAR *data, int data_len) +{ + BSTR str; - sheet = get_node_obj(stylesheet); - if(!sheet) return E_FAIL; + if (context->status != S_OK) + return; - if (FAILED(IXMLDOMNode_QueryInterface(stylesheet, &IID_IXMLDOMDocument, (void **)&owner_doc))) + if (!(str = SysAllocStringLen(data, data_len))) { - if (FAILED(hr = IXMLDOMNode_get_ownerDocument(stylesheet, &owner_doc))) - return hr; + context->status = E_OUTOFMEMORY; + return; } - sheet_doc = xmlCopyDoc(sheet->node->doc, 1); - xsltSS = xsltParseStylesheetDoc(sheet_doc); - if (xsltSS) + context->status = node_put_data(node, str); + SysFreeString(str); +} + +static HRESULT parse_context_create_text_node(struct parse_context *c, DOMNodeType type) +{ + bool preserve = is_preserving_whitespace(c->node), space = true; + bool ignored_whitespace = false; + struct domnode *node; + + if (c->status != S_OK) + return c->status; + + if (type == NODE_CDATA_SECTION) { - struct xsl_scripts scripts = { 0 }; - const char **xslparams = NULL; - xsltTransformContextPtr ctxt; - xmlDocPtr result; - unsigned int i; + parse_context_node_create(c, type, NULL, 0, NULL, 0, c->root, &node); + parse_context_node_put_data(c, node, c->buffer.data, c->buffer.count); + parse_context_append_child(c, c->node, node); - /* convert our parameter list to libxml2 format */ - if (params && params->count) - { - struct xslprocessor_par *par; + c->buffer.count = 0; - i = 0; - xslparams = malloc((params->count * 2 + 1) * sizeof(char*)); - LIST_FOR_EACH_ENTRY(par, ¶ms->list, struct xslprocessor_par, entry) + return c->status; + } + + if (c->buffer.count == 0) + return S_OK; + + if (!preserve) + { + for (size_t i = 0; i < c->buffer.count; ++i) + { + if (!xml_is_space(c->buffer.data[i])) { - xslparams[i++] = (char*)xmlchar_from_wchar(par->name); - xslparams[i++] = (char*)xmlchar_from_wchar(par->value); + space = false; + break; } - xslparams[i] = NULL; } - ctxt = xsltNewTransformContext(xsltSS, This->node->doc); + if (space) + { + c->buffer.count = 0; + ignored_whitespace = true; + } + } - node_transform_bind_scripts(ctxt, owner_doc, sheet_doc, &scripts); - ctxt->userData = &scripts; + if (c->buffer.count) + { + parse_context_node_create(c, type, NULL, 0, NULL, 0, c->root, &node); + parse_context_node_put_data(c, node, c->buffer.data, c->buffer.count); + parse_context_append_child(c, c->node, node); - if (xslparams) + c->buffer.count = 0; + } + else if (ignored_whitespace) + { + if (list_empty(&c->node->children)) { - /* push parameters to user context */ - xsltQuoteUserParams(ctxt, xslparams); - result = xsltApplyStylesheetUser(xsltSS, This->node->doc, NULL, NULL, NULL, ctxt); - - for (i = 0; i < params->count*2; i++) - free((char*)xslparams[i]); - free(xslparams); + c->node->flags |= DOMNODE_IGNORED_WS_AFTER_STARTTAG; } else { - result = xsltApplyStylesheetUser(xsltSS, This->node->doc, NULL, NULL, NULL, ctxt); + struct domnode *last_child = node_from_entry(list_tail(&c->node->children)); + last_child->flags |= DOMNODE_IGNORED_WS; } + } - for (size_t i = 0; i < scripts.count; ++i) - { - if (scripts.entries[i].script) - IActiveScript_Release(scripts.entries[i].script); - } - free(scripts.entries); + return c->status; +} - ctxt->userData = NULL; - xsltFreeTransformContext(ctxt); +static struct parse_context *impl_from_ISAXContentHandler(ISAXContentHandler *iface) +{ + return CONTAINING_RECORD(iface, struct parse_context, content_handler); +} - if (result) - { - if (stream) - hr = node_transform_write_to_stream(xsltSS, result, stream); - else - hr = node_transform_write_to_bstr(xsltSS, result, p); - xmlFreeDoc(result); - } +static struct parse_context *impl_from_ISAXExtensionHandler(ISAXExtensionHandler *iface) +{ + return CONTAINING_RECORD(iface, struct parse_context, extension_handler); +} - xsltFreeStylesheet(xsltSS); +static HRESULT WINAPI parse_content_handler_QueryInterface(ISAXContentHandler *iface, REFIID riid, void **obj) +{ + if (IsEqualGUID(riid, &IID_ISAXContentHandler) + || IsEqualGUID(riid, &IID_IUnknown)) + { + *obj = iface; + ISAXContentHandler_AddRef(iface); + return S_OK; } - else - xmlFreeDoc(sheet_doc); - if (p && !*p) *p = SysAllocStringLen(NULL, 0); + *obj = NULL; + return E_NOINTERFACE; +} - IXMLDOMDocument_Release(owner_doc); +static ULONG WINAPI parse_content_handler_AddRef(ISAXContentHandler *iface) +{ + return 2; +} - return hr; +static ULONG WINAPI parse_content_handler_Release(ISAXContentHandler *iface) +{ + return 1; } -HRESULT node_transform_node(const xmlnode *node, IXMLDOMNode *stylesheet, BSTR *p) +static HRESULT WINAPI parse_content_handler_putDocumentLocator(ISAXContentHandler *iface, ISAXLocator *locator) { - return node_transform_node_params(node, stylesheet, p, NULL, NULL); + return S_OK; } -HRESULT node_select_nodes(const xmlnode *This, BSTR query, IXMLDOMNodeList **nodes) +static HRESULT WINAPI parse_content_handler_startDocument(ISAXContentHandler *iface) { - xmlChar* str; - HRESULT hr; + return S_OK; +} - if (!query || !nodes) return E_INVALIDARG; +static HRESULT WINAPI parse_content_handler_endDocument(ISAXContentHandler *iface) +{ + return S_OK; +} - str = xmlchar_from_wchar(query); - hr = create_selection(This->node, str, nodes); - free(str); +static HRESULT WINAPI parse_content_handler_startPrefixMapping(ISAXContentHandler *iface, + const WCHAR *prefix, int prefix_len, const WCHAR *uri, int uri_len) +{ + return S_OK; +} - return hr; +static HRESULT WINAPI parse_content_handler_endPrefixMapping(ISAXContentHandler *iface, + const WCHAR *prefix, int prefix_len) +{ + return S_OK; } -HRESULT node_select_singlenode(const xmlnode *This, BSTR query, IXMLDOMNode **node) +static HRESULT WINAPI parse_content_handler_startElement(ISAXContentHandler *iface, const WCHAR *uri, int uri_len, + const WCHAR *name, int name_len, const WCHAR *qname, int qname_len, ISAXAttributes *attrs) { - IXMLDOMNodeList *list; - HRESULT hr; + struct parse_context *c = impl_from_ISAXContentHandler(iface); + struct domnode *element, *attr; + int count, length; + const WCHAR *str; - if (node) - *node = NULL; + parse_context_create_text_node(c, NODE_TEXT); + parse_context_node_create(c, NODE_ELEMENT, qname, qname_len, uri, uri_len, c->root, &element); + parse_context_append_child(c, c->node, element); + c->node = element; - hr = node_select_nodes(This, query, &list); - if (hr == S_OK) + /* TODO: error handling */ + + if (attrs) { - hr = IXMLDOMNodeList_nextNode(list, node); - IXMLDOMNodeList_Release(list); + ISAXAttributes_getLength(attrs, &count); + + for (int i = 0; i < count; ++i) + { + ISAXAttributes_getQName(attrs, i, &str, &length); + ISAXAttributes_getURI(attrs, i, &uri, &uri_len); + + parse_context_node_create(c, NODE_ATTRIBUTE, str, length, uri, uri_len, c->root, &attr); + parse_context_append_attribute(c, element, attr); + + ISAXAttributes_getValue(attrs, i, &str, &length); + parse_context_node_put_data(c, attr, str, length); + + if (attr && is_namespace_definition(attr)) + attr->flags |= DOMNODE_READONLY_VALUE; + } } - return hr; + + return c->status; } -HRESULT node_get_namespaceURI(xmlnode *This, BSTR *namespaceURI) +static HRESULT WINAPI parse_content_handler_endElement(ISAXContentHandler *iface, const WCHAR *uri, int uri_len, + const WCHAR *name, int name_len, const WCHAR *qname, int qname_len) { - xmlNsPtr ns = This->node->ns; + struct parse_context *c = impl_from_ISAXContentHandler(iface); - if(!namespaceURI) - return E_INVALIDARG; + parse_context_create_text_node(c, NODE_TEXT); + c->node = c->node->parent; + + return c->status; +} + +static HRESULT WINAPI parse_content_handler_characters(ISAXContentHandler *iface, const WCHAR *chars, int count) +{ + struct parse_context *c = impl_from_ISAXContentHandler(iface); + + string_append(&c->buffer, chars, count); + + return c->status; +} + +static HRESULT WINAPI parse_content_handler_ignorableWhitespace(ISAXContentHandler *iface, const WCHAR *chars, int count) +{ + return S_OK; +} + +static HRESULT WINAPI parse_content_handler_processingInstruction(ISAXContentHandler *iface, const WCHAR *target, + int target_len, const WCHAR *data, int data_len) +{ + struct parse_context *c = impl_from_ISAXContentHandler(iface); + struct domnode *pi; + + parse_context_create_text_node(c, NODE_TEXT); + parse_context_node_create(c, NODE_PROCESSING_INSTRUCTION, target, target_len, NULL, 0, c->root, &pi); + parse_context_append_child(c, c->node, pi); + parse_context_node_put_data(c, pi, data, data_len); - *namespaceURI = NULL; + return c->status; +} + +static HRESULT WINAPI parse_content_handler_skippedEntity(ISAXContentHandler *iface, const WCHAR *name, int name_len) +{ + return S_OK; +} + +static const ISAXContentHandlerVtbl parse_content_handler_vtbl = +{ + parse_content_handler_QueryInterface, + parse_content_handler_AddRef, + parse_content_handler_Release, + parse_content_handler_putDocumentLocator, + parse_content_handler_startDocument, + parse_content_handler_endDocument, + parse_content_handler_startPrefixMapping, + parse_content_handler_endPrefixMapping, + parse_content_handler_startElement, + parse_content_handler_endElement, + parse_content_handler_characters, + parse_content_handler_ignorableWhitespace, + parse_content_handler_processingInstruction, + parse_content_handler_skippedEntity, +}; + +static HRESULT WINAPI parse_extension_handler_QueryInterface(ISAXExtensionHandler *iface, REFIID riid, void **obj) +{ + if (IsEqualGUID(riid, &IID_ISAXExtensionHandler) + || IsEqualGUID(riid, &IID_IUnknown)) + { + *obj = iface; + ISAXExtensionHandler_AddRef(iface); + return S_OK; + } - if (ns && ns->href) - *namespaceURI = bstr_from_xmlChar(ns->href); + *obj = NULL; + return E_NOINTERFACE; +} - TRACE("uri: %s\n", debugstr_w(*namespaceURI)); +static ULONG WINAPI parse_extension_handler_AddRef(ISAXExtensionHandler *iface) +{ + return 2; +} - return *namespaceURI ? S_OK : S_FALSE; +static ULONG WINAPI parse_extension_handler_Release(ISAXExtensionHandler *iface) +{ + return 1; } -HRESULT node_get_prefix(xmlnode *This, BSTR *prefix) +static HRESULT WINAPI parse_extension_handler_xmldecl(ISAXExtensionHandler *iface, + BSTR version, BSTR encoding, BSTR standalone) { - xmlNsPtr ns = This->node->ns; + struct parse_context *c = impl_from_ISAXExtensionHandler(iface); + struct domnode *pi, *node; - if (!prefix) return E_INVALIDARG; + parse_context_node_create(c, NODE_PROCESSING_INSTRUCTION, L"xml", 3, NULL, 0, c->root, &pi); + parse_context_append_child(c, c->root, pi); - *prefix = NULL; + parse_context_node_create(c, NODE_ATTRIBUTE, L"version", 7, NULL, 0, c->root, &node); - if (ns && ns->prefix) - *prefix = bstr_from_xmlChar(ns->prefix); + parse_context_node_put_data(c, node, version, SysStringLen(version)); + parse_context_append_attribute(c, pi, node); - TRACE("prefix: %s\n", debugstr_w(*prefix)); + if (encoding) + { + parse_context_node_create(c, NODE_ATTRIBUTE, L"encoding", 8, NULL, 0, c->root, &node); + parse_context_node_put_data(c, node, encoding, SysStringLen(encoding)); + parse_context_append_attribute(c, pi, node); + } + + if (standalone) + { + parse_context_node_create(c, NODE_ATTRIBUTE, L"standalone", 10, NULL, 0, c->root, &node); + parse_context_node_put_data(c, node, standalone, SysStringLen(standalone)); + parse_context_append_attribute(c, pi, node); + } - return *prefix ? S_OK : S_FALSE; + return c->status; } -HRESULT node_get_base_name(xmlnode *This, BSTR *name) +static HRESULT WINAPI parse_extension_handler_dtd(ISAXExtensionHandler *iface, BSTR data) { - if (!name) return E_INVALIDARG; - - if (xmldoc_version(This->node->doc) != MSXML6 && - xmlStrEqual(This->node->name, BAD_CAST "xmlns")) - *name = SysAllocString(L""); - else - *name = bstr_from_xmlChar(This->node->name); - if (!*name) return E_OUTOFMEMORY; + struct parse_context *c = impl_from_ISAXExtensionHandler(iface); - TRACE("returning %s\n", debugstr_w(*name)); + if (c->node && c->node->type == NODE_DOCUMENT_TYPE) + { + if (!(c->node->data = SysAllocStringLen(data, SysStringLen(data)))) + c->status = E_OUTOFMEMORY; + } - return S_OK; + return c->status; } -void destroy_xmlnode(xmlnode *This) +static const ISAXExtensionHandlerVtbl parse_extension_handler_vtbl = { - if(This->node) - { - xmlnode_release(This->node); - xmldoc_release(This->node->doc); - } + parse_extension_handler_QueryInterface, + parse_extension_handler_AddRef, + parse_extension_handler_Release, + parse_extension_handler_xmldecl, + parse_extension_handler_dtd, +}; + +static struct parse_context *impl_from_ISAXLexicalHandler(ISAXLexicalHandler *iface) +{ + return CONTAINING_RECORD(iface, struct parse_context, lexical_handler); } -void init_xmlnode(xmlnode *This, xmlNodePtr node, IXMLDOMNode *node_iface, dispex_static_data_t *dispex_data) +static HRESULT WINAPI parse_lexical_handler_QueryInterface(ISAXLexicalHandler *iface, REFIID riid, void **obj) { - if(node) + if (IsEqualGUID(riid, &IID_ISAXLexicalHandler) + || IsEqualGUID(riid, &IID_IUnknown)) { - xmlnode_add_ref(node); - xmldoc_add_ref(node->doc); + *obj = iface; + ISAXLexicalHandler_AddRef(iface); + return S_OK; } - This->node = node; - This->iface = node_iface; - This->parent = NULL; - - init_dispex(&This->dispex, (IUnknown*)This->iface, dispex_data); + *obj = NULL; + return E_NOINTERFACE; } -typedef struct { - xmlnode node; - IXMLDOMNode IXMLDOMNode_iface; - LONG ref; -} unknode; - -static inline unknode *unknode_from_IXMLDOMNode(IXMLDOMNode *iface) +static ULONG WINAPI parse_lexical_handler_AddRef(ISAXLexicalHandler *iface) { - return CONTAINING_RECORD(iface, unknode, IXMLDOMNode_iface); + return 2; } -static HRESULT WINAPI unknode_QueryInterface( - IXMLDOMNode *iface, - REFIID riid, - void** ppvObject ) +static ULONG WINAPI parse_lexical_handler_Release(ISAXLexicalHandler *iface) { - unknode *This = unknode_from_IXMLDOMNode( iface ); + return 1; +} - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); +static HRESULT WINAPI parse_lexical_handler_startDTD(ISAXLexicalHandler *iface, + const WCHAR *name, int name_len, const WCHAR *pubid, int pubid_len, + const WCHAR *sysid, int sysid_len) +{ + struct parse_context *c = impl_from_ISAXLexicalHandler(iface); + struct domnode *dtd; - if (IsEqualGUID(riid, &IID_IUnknown)) { - *ppvObject = iface; - }else if (IsEqualGUID( riid, &IID_IDispatch) || - IsEqualGUID( riid, &IID_IXMLDOMNode)) { - *ppvObject = &This->IXMLDOMNode_iface; - }else if(node_query_interface(&This->node, riid, ppvObject)) { - return *ppvObject ? S_OK : E_NOINTERFACE; - }else { - FIXME("interface %s not implemented\n", debugstr_guid(riid)); - *ppvObject = NULL; - return E_NOINTERFACE; - } + parse_context_node_create(c, NODE_DOCUMENT_TYPE, name, name_len, NULL, 0, c->root, &dtd); + parse_context_append_child(c, c->root, dtd); + c->node = dtd; - IUnknown_AddRef((IUnknown*)*ppvObject); - return S_OK; + return c->status; } -static ULONG WINAPI unknode_AddRef( - IXMLDOMNode *iface ) +static HRESULT WINAPI parse_lexical_handler_endDTD(ISAXLexicalHandler *iface) { - unknode *This = unknode_from_IXMLDOMNode( iface ); + struct parse_context *c = impl_from_ISAXLexicalHandler(iface); - return InterlockedIncrement(&This->ref); + if (c->node) + c->node = c->node->parent; + + return S_OK; } -static ULONG WINAPI unknode_Release( - IXMLDOMNode *iface ) +static HRESULT WINAPI parse_lexical_handler_startEntity(ISAXLexicalHandler *iface, + const WCHAR *name, int name_len) { - unknode *This = unknode_from_IXMLDOMNode( iface ); - LONG ref; + return S_OK; +} - ref = InterlockedDecrement( &This->ref ); - if(!ref) { - destroy_xmlnode(&This->node); - free(This); - } +static HRESULT WINAPI parse_lexical_handler_endEntity(ISAXLexicalHandler *iface, + const WCHAR *name, int name_len) +{ + return S_OK; +} - return ref; +static HRESULT WINAPI parse_lexical_handler_startCDATA(ISAXLexicalHandler *iface) +{ + struct parse_context *c = impl_from_ISAXLexicalHandler(iface); + return parse_context_create_text_node(c, NODE_TEXT); } -static HRESULT WINAPI unknode_GetTypeInfoCount( - IXMLDOMNode *iface, - UINT* pctinfo ) +static HRESULT WINAPI parse_lexical_handler_endCDATA(ISAXLexicalHandler *iface) { - unknode *This = unknode_from_IXMLDOMNode( iface ); + struct parse_context *c = impl_from_ISAXLexicalHandler(iface); + return parse_context_create_text_node(c, NODE_CDATA_SECTION); +} - TRACE("(%p)->(%p)\n", This, pctinfo); +static HRESULT WINAPI parse_lexical_handler_comment(ISAXLexicalHandler *iface, const WCHAR *chars, int count) +{ + struct parse_context *c = impl_from_ISAXLexicalHandler(iface); + struct domnode *comment; - *pctinfo = 1; + parse_context_create_text_node(c, NODE_TEXT); + parse_context_node_create(c, NODE_COMMENT, NULL, 0, NULL, 0, c->root, &comment); + parse_context_append_child(c, c->node, comment); + parse_context_node_put_data(c, comment, chars, count); - return S_OK; + return c->status; } -static HRESULT WINAPI unknode_GetTypeInfo( - IXMLDOMNode *iface, - UINT iTInfo, - LCID lcid, - ITypeInfo** ppTInfo ) +static const ISAXLexicalHandlerVtbl parse_lexical_handler_vtbl = { - TRACE("%p, %u, %lx, %p.\n", iface, iTInfo, lcid, ppTInfo); + parse_lexical_handler_QueryInterface, + parse_lexical_handler_AddRef, + parse_lexical_handler_Release, + parse_lexical_handler_startDTD, + parse_lexical_handler_endDTD, + parse_lexical_handler_startEntity, + parse_lexical_handler_endEntity, + parse_lexical_handler_startCDATA, + parse_lexical_handler_endCDATA, + parse_lexical_handler_comment, +}; - return get_typeinfo(IXMLDOMNode_tid, ppTInfo); -} +struct domdoc_properties *domdoc_create_properties(MSXML_VERSION version); -static HRESULT WINAPI unknode_GetIDsOfNames( - IXMLDOMNode *iface, - REFIID riid, - LPOLESTR* rgszNames, - UINT cNames, - LCID lcid, - DISPID* rgDispId ) +static HRESULT parse_context_init(struct parse_context *c, VARIANT_BOOL preserving) { - ITypeInfo *typeinfo; + IUnknown *unk; HRESULT hr; + VARIANT v; - TRACE("%p, %s, %p, %u, %lx, %p.\n", iface, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); + memset(c, 0, sizeof(*c)); + c->content_handler.lpVtbl = &parse_content_handler_vtbl; + c->extension_handler.lpVtbl = &parse_extension_handler_vtbl; + c->lexical_handler.lpVtbl = &parse_lexical_handler_vtbl; + c->buffer.status = &c->status; - if(!rgszNames || cNames == 0 || !rgDispId) - return E_INVALIDARG; + if (FAILED(hr = SAXXMLReader_create(MSXML3, (void **)&unk))) + return hr; - hr = get_typeinfo(IXMLDOMNode_tid, &typeinfo); - if(SUCCEEDED(hr)) - { - hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); - ITypeInfo_Release(typeinfo); - } + IUnknown_QueryInterface(unk, &IID_ISAXXMLReader, (void **)&c->reader); + IUnknown_QueryInterface(unk, &IID_ISAXXMLReaderExtension, (void **)&c->reader_extension); + IUnknown_Release(unk); + + ISAXXMLReader_putContentHandler(c->reader, &c->content_handler); + + V_VT(&v) = VT_UNKNOWN; + V_UNKNOWN(&v) = (IUnknown *)&c->lexical_handler; + ISAXXMLReader_putProperty(c->reader, L"http://xml.org/sax/properties/lexical-handler", v); + + V_VT(&v) = VT_UNKNOWN; + V_UNKNOWN(&v) = (IUnknown *)&c->extension_handler; + ISAXXMLReader_putProperty(c->reader, L"http://winehq.org/sax/properties/extension-handler", v); + + domnode_create(NODE_DOCUMENT, NULL, 0, NULL, 0, NULL, &c->root); + c->root->properties = domdoc_create_properties(MSXML_DEFAULT); + c->root->properties->preserving = preserving; + c->node = c->root; return hr; } -static HRESULT WINAPI unknode_Invoke( - IXMLDOMNode *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS* pDispParams, - VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, - UINT* puArgErr ) +static void parse_context_cleanup(struct parse_context *c) +{ + free(c->buffer.data); + if (c->reader) + ISAXXMLReader_Release(c->reader); + if (c->reader_extension) + ISAXXMLReaderExtension_Release(c->reader_extension); +} + +HRESULT parse_stream(ISequentialStream *stream, bool utf16, VARIANT_BOOL preserve, struct domnode **tree) { - ITypeInfo *typeinfo; + struct parse_context context; HRESULT hr; + VARIANT v; + + *tree = NULL; + + if (FAILED(hr = parse_context_init(&context, preserve))) + return hr; - TRACE("%p, %ld, %s, %lx, %d, %p, %p, %p, %p.\n", iface, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + if (utf16) + { + hr = ISAXXMLReaderExtension_parseUTF16(context.reader_extension, stream); + } + else + { + V_VT(&v) = VT_UNKNOWN; + V_UNKNOWN(&v) = (IUnknown *)stream; + hr = ISAXXMLReader_parse(context.reader, v); + } - hr = get_typeinfo(IXMLDOMNode_tid, &typeinfo); - if(SUCCEEDED(hr)) + if (hr == S_OK) { - hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags, pDispParams, - pVarResult, pExcepInfo, puArgErr); - ITypeInfo_Release(typeinfo); + *tree = context.root; + context.root = NULL; } + parse_context_cleanup(&context); + return hr; } -static HRESULT WINAPI unknode_get_nodeName( - IXMLDOMNode *iface, - BSTR* p ) +struct xmldoc_context { - unknode *This = unknode_from_IXMLDOMNode( iface ); + xmlDocPtr xmldoc; + struct domnode *node; + xmlNodePtr *xmlnode; + xmlNodePtr tree; +}; - FIXME("(%p)->(%p)\n", This, p); +static xmlNsPtr xmlnode_get_ns(xmlNodePtr tree, struct domnode *node, xmlNodePtr element) +{ + xmlChar *uri, *prefix; + xmlNsPtr ns; - return node_get_nodeName(&This->node, p); -} + if (!node->uri) + return NULL; -static HRESULT WINAPI unknode_get_nodeValue( - IXMLDOMNode *iface, - VARIANT* value) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); + uri = xmlchar_from_wchar(node->uri); + prefix = node->prefix ? xmlchar_from_wchar(node->prefix) : NULL; - FIXME("(%p)->(%p)\n", This, value); + if ((ns = xmlSearchNs(tree->doc, element, prefix))) + { + if (!xmlStrEqual(ns->href, uri)) + ns = xmlNewNs(element, uri, prefix); + } + else + { + ns = xmlNewNs(element, uri, prefix); + } - if(!value) - return E_INVALIDARG; + free(uri); + free(prefix); - V_VT(value) = VT_NULL; - return S_FALSE; + return ns; } -static HRESULT WINAPI unknode_put_nodeValue( - IXMLDOMNode *iface, - VARIANT value) +static xmlNodePtr create_xmlnode_element(struct xmldoc_context *context, struct domnode *node) { - unknode *This = unknode_from_IXMLDOMNode( iface ); - FIXME("(%p)->(v%d)\n", This, V_VT(&value)); - return E_FAIL; -} + xmlChar *name, *value, *uri, *prefix; + struct domnode *attr; + xmlNodePtr xmlnode; + xmlAttrPtr xmlattr; + xmlNsPtr ns; + BSTR text; -static HRESULT WINAPI unknode_get_nodeType( - IXMLDOMNode *iface, - DOMNodeType* domNodeType ) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); + name = xmlchar_from_wchar(node->name); + xmlnode = xmlNewDocNode(context->xmldoc, NULL, name, NULL); + xmlAddChild(context->tree, xmlnode); + free(name); - FIXME("(%p)->(%p)\n", This, domNodeType); + ns = xmlnode_get_ns(context->tree, node, xmlnode); + xmlSetNs(xmlnode, ns); - switch (This->node.node->type) + /* Add explicit definitions first. */ + LIST_FOR_EACH_ENTRY(attr, &node->attributes, struct domnode, entry) { - case XML_ELEMENT_NODE: - case XML_ATTRIBUTE_NODE: - case XML_TEXT_NODE: - case XML_CDATA_SECTION_NODE: - case XML_ENTITY_REF_NODE: - case XML_ENTITY_NODE: - case XML_PI_NODE: - case XML_COMMENT_NODE: - case XML_DOCUMENT_NODE: - case XML_DOCUMENT_TYPE_NODE: - case XML_DOCUMENT_FRAG_NODE: - case XML_NOTATION_NODE: - /* we only care about this set of types, libxml2 type values are - exactly what we need */ - *domNodeType = (DOMNodeType)This->node.node->type; - break; - default: - *domNodeType = NODE_INVALID; - break; + if ((attr->prefix && !wcscmp(attr->prefix, L"xmlns")) + || !wcscmp(attr->qname, L"xmlns")) + { + node_get_text(attr, &text); + uri = xmlchar_from_wchar(text); + prefix = wcscmp(attr->qname, L"xmlns") ? xmlchar_from_wchar(attr->name) : NULL; + + xmlNewNs(xmlnode, uri, prefix); + + SysFreeString(text); + free(prefix); + free(uri); + } } - return S_OK; -} + LIST_FOR_EACH_ENTRY(attr, &node->attributes, struct domnode, entry) + { + if ((attr->prefix && !wcscmp(attr->prefix, L"xmlns")) + || !wcscmp(attr->qname, L"xmlns")) + { + continue; + } -static HRESULT WINAPI unknode_get_parentNode( - IXMLDOMNode *iface, - IXMLDOMNode** parent ) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - FIXME("(%p)->(%p)\n", This, parent); - if (!parent) return E_INVALIDARG; - *parent = NULL; - return S_FALSE; -} + node_get_text(attr, &text); -static HRESULT WINAPI unknode_get_childNodes( - IXMLDOMNode *iface, - IXMLDOMNodeList** outList) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); + name = xmlchar_from_wchar(attr->name); + value = xmlchar_from_wchar(text); - TRACE("(%p)->(%p)\n", This, outList); + ns = xmlnode_get_ns(xmlnode, attr, xmlnode); + xmlattr = xmlNewProp(xmlnode, name, value); + xmlattr->_private2 = attr; + xmlSetNs((xmlNodePtr)xmlattr, ns); - return node_get_child_nodes(&This->node, outList); + if (context->node == attr) + *context->xmlnode = (xmlNodePtr)xmlattr; + + SysFreeString(text); + free(value); + free(name); + } + + return xmlnode; } -static HRESULT WINAPI unknode_get_firstChild( - IXMLDOMNode *iface, - IXMLDOMNode** domNode) +static xmlDtdPtr create_xmldtd_from_domnode(struct domnode *node) { - unknode *This = unknode_from_IXMLDOMNode( iface ); + struct string_buffer buffer; + xmlDtdPtr dtd = NULL; + xmlDocPtr doc; + BSTR str; - TRACE("(%p)->(%p)\n", This, domNode); + string_buffer_init(&buffer); - return node_get_first_child(&This->node, domNode); -} + string_append(&buffer, L"<?xml version=\"1.0\"?>", 21); + string_append(&buffer, node->data, SysStringLen(node->data)); + string_append(&buffer, L"<a/>", 4); + string_to_bstr(&buffer, &str); -static HRESULT WINAPI unknode_get_lastChild( - IXMLDOMNode *iface, - IXMLDOMNode** domNode) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); + doc = xmlParseMemory((const char *)str, SysStringByteLen(str)); + SysFreeString(str); - TRACE("(%p)->(%p)\n", This, domNode); + if ((dtd = xmlGetIntSubset(doc))) + dtd = xmlCopyDtd(dtd); + xmlFreeDoc(doc); - return node_get_last_child(&This->node, domNode); + return dtd; } -static HRESULT WINAPI unknode_get_previousSibling( - IXMLDOMNode *iface, - IXMLDOMNode** domNode) +static xmlNodePtr create_xmlnode_from_domnode(struct xmldoc_context *context, struct domnode *node) { - unknode *This = unknode_from_IXMLDOMNode( iface ); + xmlNodePtr xmlnode = NULL, old_tree; + xmlChar *name, *data; + struct domnode *n; + xmlDtdPtr dtd; - TRACE("(%p)->(%p)\n", This, domNode); + name = xmlchar_from_wchar(node->name); + data = xmlchar_from_wchar(node->data); - return node_get_previous_sibling(&This->node, domNode); -} + switch (node->type) + { + case NODE_ELEMENT: + xmlnode = create_xmlnode_element(context, node); + break; + case NODE_COMMENT: + xmlnode = xmlNewDocComment(context->xmldoc, data); + xmlAddChild(context->tree, xmlnode); + break; + case NODE_TEXT: + xmlnode = xmlNewDocText(context->xmldoc, data); + xmlAddChild(context->tree, xmlnode); + break; + case NODE_PROCESSING_INSTRUCTION: + xmlnode = xmlNewDocPI(context->xmldoc, name, data); + xmlAddChild(context->tree, xmlnode); + break; + case NODE_CDATA_SECTION: + xmlnode = xmlNewCDataBlock(context->xmldoc, data, xmlStrlen(data)); + xmlAddChild(context->tree, xmlnode); + break; + case NODE_DOCUMENT_TYPE: + dtd = create_xmldtd_from_domnode(node); + context->xmldoc->intSubset = dtd; + break; + default: + FIXME("Not supported for node type %d.\n", node->type); + break; + } -static HRESULT WINAPI unknode_get_nextSibling( - IXMLDOMNode *iface, - IXMLDOMNode** domNode) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); + free(name); + free(data); - TRACE("(%p)->(%p)\n", This, domNode); + if (!xmlnode) + return NULL; - return node_get_next_sibling(&This->node, domNode); -} + xmlnode->_private2 = node; -static HRESULT WINAPI unknode_get_attributes( - IXMLDOMNode *iface, - IXMLDOMNamedNodeMap** attributeMap) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); + if (context->node == node) + *context->xmlnode = xmlnode; - FIXME("(%p)->(%p)\n", This, attributeMap); + old_tree = context->tree; + if (node->type == NODE_ELEMENT) context->tree = xmlnode; + LIST_FOR_EACH_ENTRY(n, &node->children, struct domnode, entry) + { + create_xmlnode_from_domnode(context, n); + } + context->tree = old_tree; - return return_null_ptr((void**)attributeMap); + return xmlnode; } -static HRESULT WINAPI unknode_insertBefore( - IXMLDOMNode *iface, - IXMLDOMNode* newNode, VARIANT refChild, - IXMLDOMNode** outOldNode) +/* Create a whole libxml document tree, return pointer to corresponding node as well */ +xmlDocPtr create_xmldoc_from_domdoc(struct domnode *node, xmlNodePtr *xmlnode) { - unknode *This = unknode_from_IXMLDOMNode( iface ); + struct xmldoc_context context = { 0 }; + struct domnode *n, *doc; + xmlDocPtr xmldoc; - FIXME("(%p)->(%p x%d %p)\n", This, newNode, V_VT(&refChild), outOldNode); + *xmlnode = NULL; - return node_insert_before(&This->node, newNode, &refChild, outOldNode); -} + doc = node->owner ? node->owner : node; + xmldoc = xmlNewDoc(NULL); + xmldoc->_private2 = doc; -static HRESULT WINAPI unknode_replaceChild( - IXMLDOMNode *iface, - IXMLDOMNode* newNode, - IXMLDOMNode* oldNode, - IXMLDOMNode** outOldNode) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); + context.xmldoc = xmldoc; + context.node = node; + context.xmlnode = xmlnode; - FIXME("(%p)->(%p %p %p)\n", This, newNode, oldNode, outOldNode); + if (node == doc) + *context.xmlnode = (xmlNodePtr)xmldoc; - return node_replace_child(&This->node, newNode, oldNode, outOldNode); -} + context.tree = (xmlNodePtr)xmldoc; + LIST_FOR_EACH_ENTRY(n, &doc->children, struct domnode, entry) + { + create_xmlnode_from_domnode(&context, n); + } -static HRESULT WINAPI unknode_removeChild( - IXMLDOMNode *iface, - IXMLDOMNode* domNode, IXMLDOMNode** oldNode) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_remove_child(&This->node, domNode, oldNode); + return xmldoc; } -static HRESULT WINAPI unknode_appendChild( - IXMLDOMNode *iface, - IXMLDOMNode* newNode, IXMLDOMNode** outNewNode) +HRESULT node_save(struct domnode *doc, IStream *stream) { - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_append_child(&This->node, newNode, outNewNode); -} + struct node_dump_context context = { 0 }; + struct domnode *child, *attr, *node; + const WCHAR *encoding = NULL; + UINT codepage; -static HRESULT WINAPI unknode_hasChildNodes( - IXMLDOMNode *iface, - VARIANT_BOOL* pbool) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_has_childnodes(&This->node, pbool); -} + assert(doc->type == NODE_DOCUMENT); -static HRESULT WINAPI unknode_get_ownerDocument( - IXMLDOMNode *iface, - IXMLDOMDocument** domDocument) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_get_owner_doc(&This->node, domDocument); -} + /* Get desired encoding from declaration. */ + if ((child = domnode_get_first_child(doc))) + { + if (child->type == NODE_PROCESSING_INSTRUCTION && !wcscmp(child->name, L"xml")) + { + if (domnode_get_attribute(child, L"encoding", &attr) == S_OK) + { + if ((node = domnode_get_first_child(attr))) + encoding = node->data; + } + } + } -static HRESULT WINAPI unknode_cloneNode( - IXMLDOMNode *iface, - VARIANT_BOOL pbool, IXMLDOMNode** outNode) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_clone(&This->node, pbool, outNode ); -} + if (!encoding) + encoding = L"UTF-8"; -static HRESULT WINAPI unknode_get_nodeTypeString( - IXMLDOMNode *iface, - BSTR* p) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); + TRACE("Using %s encoding.\n", debugstr_w(encoding)); - FIXME("(%p)->(%p)\n", This, p); + if (!(codepage = get_codepage_for_encoding(encoding))) + { + FIXME("Unrecognized output encoding %s.\n", debugstr_w(encoding)); + return E_FAIL; + } - return node_get_nodeName(&This->node, p); -} + node_dump_context_init(&context, codepage, stream); -static HRESULT WINAPI unknode_get_text( - IXMLDOMNode *iface, - BSTR* p) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_get_text(&This->node, p); -} + LIST_FOR_EACH_ENTRY(node, &doc->children, struct domnode, entry) + { + node_dump(node, &context); + node_dump_append(&context, L"\r\n", 2); + } -static HRESULT WINAPI unknode_put_text( - IXMLDOMNode *iface, - BSTR p) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_put_text(&This->node, p); + return node_dump_context_cleanup(&context); } -static HRESULT WINAPI unknode_get_specified( - IXMLDOMNode *iface, - VARIANT_BOOL* isSpecified) +static HRESULT create_xpath_query_for_tagname(const BSTR name, BSTR *query) { - unknode *This = unknode_from_IXMLDOMNode( iface ); - FIXME("(%p)->(%p) stub!\n", This, isSpecified); - *isSpecified = VARIANT_TRUE; - return S_OK; -} + struct string_buffer buffer; + const WCHAR *p, *end; -static HRESULT WINAPI unknode_get_definition( - IXMLDOMNode *iface, - IXMLDOMNode** definitionNode) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - FIXME("(%p)->(%p)\n", This, definitionNode); - return E_NOTIMPL; -} + *query = NULL; -static HRESULT WINAPI unknode_get_nodeTypedValue( - IXMLDOMNode *iface, - VARIANT* var1) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - FIXME("(%p)->(%p)\n", This, var1); - return return_null_var(var1); -} + string_buffer_init(&buffer); -static HRESULT WINAPI unknode_put_nodeTypedValue( - IXMLDOMNode *iface, - VARIANT typedValue) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); - return E_NOTIMPL; -} + /* Special case - empty tagname - means select all nodes, + except document itself. */ + if (!*name) + { + string_append(&buffer, L"/descendant::node()", 19); + return string_to_bstr(&buffer, query); + } -static HRESULT WINAPI unknode_get_dataType( - IXMLDOMNode *iface, - VARIANT* var1) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - TRACE("(%p)->(%p)\n", This, var1); - return return_null_var(var1); + string_append(&buffer, L"descendant::", 12); + + p = name; + while (p && *p) + { + switch (*p) + { + case '/': + case '*': + string_append(&buffer, p, 1); + ++p; + break; + default: + string_append(&buffer, L"*[local-name()='", 16); + end = p; + while (*end && *end != '/') + ++end; + string_append(&buffer, p, end - p); + p = end; + string_append(&buffer, L"']", 2); + } + } + + return string_to_bstr(&buffer, query); } -static HRESULT WINAPI unknode_put_dataType( - IXMLDOMNode *iface, - BSTR p) +HRESULT node_get_elements_by_tagname(struct domnode *node, BSTR name, IXMLDOMNodeList **list) { - unknode *This = unknode_from_IXMLDOMNode( iface ); - - FIXME("(%p)->(%s)\n", This, debugstr_w(p)); + BSTR query; + HRESULT hr; - if(!p) + if (!name || !list) return E_INVALIDARG; - return E_FAIL; + hr = create_xpath_query_for_tagname(name, &query); + if (SUCCEEDED(hr)) + hr = create_selection(node, query, true, list); + SysFreeString(query); + + return hr; } -static HRESULT WINAPI unknode_get_xml( - IXMLDOMNode *iface, - BSTR* p) +XDR_DT node_get_data_type(const struct domnode *node) { - unknode *This = unknode_from_IXMLDOMNode( iface ); + struct domnode *doc = node->owner, *attr; + IXMLDOMSchemaCollection2 *schema; + XDR_DT dt = DT_INVALID; + HRESULT hr; + BSTR value; - FIXME("(%p)->(%p)\n", This, p); + if (node->type != NODE_ELEMENT) + return dt; - return node_get_xml(&This->node, FALSE, p); -} + if (is_same_uri(node, L"urn:schemas-microsoft-com:datatypes")) + { + dt = bstr_to_dt(node->name, -1); + } + else + { + domnode_get_qualified_attribute(node, L"dt", L"urn:schemas-microsoft-com:datatypes", &attr); + if (attr) + { + if (FAILED(hr = node_get_text(attr, &value))) + return dt; -static HRESULT WINAPI unknode_transformNode( - IXMLDOMNode *iface, - IXMLDOMNode* domNode, BSTR* p) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_transform_node(&This->node, domNode, p); -} + dt = bstr_to_dt(value, -1); + SysFreeString(value); + } + else if ((schema = doc->properties->schemaCache)) + { + dt = SchemaCache_get_node_dt(schema, node->name, node->uri); + } + } -static HRESULT WINAPI unknode_selectNodes( - IXMLDOMNode *iface, - BSTR p, IXMLDOMNodeList** outList) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_select_nodes(&This->node, p, outList); + TRACE("=> dt:%s\n", debugstr_dt(dt)); + return dt; } -static HRESULT WINAPI unknode_selectSingleNode( - IXMLDOMNode *iface, - BSTR p, IXMLDOMNode** outNode) +HRESULT create_attribute_node(const WCHAR *name, const WCHAR *uri, struct domnode *owner, IXMLDOMNode **ret) { - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_select_singlenode(&This->node, p, outNode); -} + struct domnode *attr; + HRESULT hr; -static HRESULT WINAPI unknode_get_parsed( - IXMLDOMNode *iface, - VARIANT_BOOL* isParsed) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - FIXME("(%p)->(%p) stub!\n", This, isParsed); - *isParsed = VARIANT_TRUE; - return S_OK; -} + *ret = NULL; -static HRESULT WINAPI unknode_get_namespaceURI( - IXMLDOMNode *iface, - BSTR* p) -{ - unknode *This = unknode_from_IXMLDOMNode( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_namespaceURI(&This->node, p); + if (FAILED(hr = domnode_create(NODE_ATTRIBUTE, name, wcslen(name), uri, wcslen(uri), owner, &attr))) + return hr; + + return create_node(attr, ret); } -static HRESULT WINAPI unknode_get_prefix( - IXMLDOMNode *iface, - BSTR* p) +static void LIBXML2_LOG_CALLBACK validate_error(void* ctx, char const* msg, ...) { - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_get_prefix(&This->node, p); + va_list ap; + va_start(ap, msg); + LIBXML2_CALLBACK_ERR(domdoc_validateNode, msg, ap); + va_end(ap); } -static HRESULT WINAPI unknode_get_baseName( - IXMLDOMNode *iface, - BSTR* p) +static void LIBXML2_LOG_CALLBACK validate_warning(void* ctx, char const* msg, ...) { - unknode *This = unknode_from_IXMLDOMNode( iface ); - return node_get_base_name(&This->node, p); + va_list ap; + va_start(ap, msg); + LIBXML2_CALLBACK_WARN(domdoc_validateNode, msg, ap); + va_end(ap); } -static HRESULT WINAPI unknode_transformNodeToObject( - IXMLDOMNode *iface, - IXMLDOMNode* domNode, VARIANT var1) +HRESULT node_validate(struct domnode *doc, IXMLDOMNode *node_obj, IXMLDOMParseError **err) { - unknode *This = unknode_from_IXMLDOMNode( iface ); - FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); - return E_NOTIMPL; -} + IXMLDOMSchemaCollection2 *schema; + struct domnode *node; + LONG err_code = 0; + HRESULT hr = S_OK; + int validated = 0; + xmlDocPtr xmldoc; + xmlNodePtr xmlnode; -static const struct IXMLDOMNodeVtbl unknode_vtbl = -{ - unknode_QueryInterface, - unknode_AddRef, - unknode_Release, - unknode_GetTypeInfoCount, - unknode_GetTypeInfo, - unknode_GetIDsOfNames, - unknode_Invoke, - unknode_get_nodeName, - unknode_get_nodeValue, - unknode_put_nodeValue, - unknode_get_nodeType, - unknode_get_parentNode, - unknode_get_childNodes, - unknode_get_firstChild, - unknode_get_lastChild, - unknode_get_previousSibling, - unknode_get_nextSibling, - unknode_get_attributes, - unknode_insertBefore, - unknode_replaceChild, - unknode_removeChild, - unknode_appendChild, - unknode_hasChildNodes, - unknode_get_ownerDocument, - unknode_cloneNode, - unknode_get_nodeTypeString, - unknode_get_text, - unknode_put_text, - unknode_get_specified, - unknode_get_definition, - unknode_get_nodeTypedValue, - unknode_put_nodeTypedValue, - unknode_get_dataType, - unknode_put_dataType, - unknode_get_xml, - unknode_transformNode, - unknode_selectNodes, - unknode_selectSingleNode, - unknode_get_parsed, - unknode_get_namespaceURI, - unknode_get_prefix, - unknode_get_baseName, - unknode_transformNodeToObject -}; + if (!(node = get_node_obj(node_obj))) + return E_FAIL; -IXMLDOMNode *create_node( xmlNodePtr node ) -{ - IUnknown *pUnk; - IXMLDOMNode *ret; - HRESULT hr; + if (node->owner != doc && node != doc) + { + if (err) + *err = create_parseError(err_code, NULL, NULL, NULL, 0, 0, 0); + return E_FAIL; + } - if ( !node ) - return NULL; + /* TODO: for now simply treat empty document as not well-formed */ + if (list_empty(&node->children)) + { + if (err) + *err = create_parseError(E_XML_NOTWF, NULL, NULL, NULL, 0, 0, 0); + return S_FALSE; + } - TRACE("type %d\n", node->type); - switch(node->type) + xmldoc = create_xmldoc_from_domdoc(node, &xmlnode); + + /* DTD validation */ + if (xmldoc->intSubset || xmldoc->extSubset) { - case XML_ELEMENT_NODE: - pUnk = create_element( node ); - break; - case XML_ATTRIBUTE_NODE: - pUnk = create_attribute( node, FALSE ); - break; - case XML_TEXT_NODE: - pUnk = create_text( node ); - break; - case XML_CDATA_SECTION_NODE: - pUnk = create_cdata( node ); - break; - case XML_ENTITY_REF_NODE: - pUnk = create_doc_entity_ref( node ); - break; - case XML_PI_NODE: - pUnk = create_pi( node ); - break; - case XML_COMMENT_NODE: - pUnk = create_comment( node ); - break; - case XML_DOCUMENT_NODE: - pUnk = create_domdoc( node ); - break; - case XML_DOCUMENT_FRAG_NODE: - pUnk = create_doc_fragment( node ); - break; - case XML_DTD_NODE: - case XML_DOCUMENT_TYPE_NODE: - pUnk = create_doc_type( node ); - break; - case XML_ENTITY_NODE: - case XML_NOTATION_NODE: { - unknode *new_node; + xmlValidCtxtPtr vctx = xmlNewValidCtxt(); + int ret; - FIXME("only creating basic node for type %d\n", node->type); + vctx->error = validate_error; + vctx->warning = validate_warning; + ++validated; - new_node = malloc(sizeof(unknode)); - if(!new_node) - return NULL; + ret = node == doc ? xmlValidateDocument(vctx, xmldoc) : xmlValidateElement(vctx, xmldoc, xmlnode); + if (!ret) + { + /* TODO: get a real error code here */ + TRACE("DTD validation failed\n"); + err_code = E_XML_INVALID; + hr = S_FALSE; + } + xmlFreeValidCtxt(vctx); + } - new_node->IXMLDOMNode_iface.lpVtbl = &unknode_vtbl; - new_node->ref = 1; - init_xmlnode(&new_node->node, node, &new_node->IXMLDOMNode_iface, NULL); - pUnk = (IUnknown*)&new_node->IXMLDOMNode_iface; - break; + /* Schema validation */ + schema = doc->properties->schemaCache; + if (hr == S_OK && schema) + { + + hr = SchemaCache_validate_tree(schema, xmlnode); + if (SUCCEEDED(hr)) + { + ++validated; + /* TODO: get a real error code here */ + if (hr == S_OK) + { + TRACE("schema validation succeeded\n"); + } + else + { + WARN("schema validation failed\n"); + err_code = E_XML_INVALID; + } + } + else + { + /* not really OK, just didn't find a schema for the ns */ + hr = S_OK; + } } - default: - ERR("Called for unsupported node type %d\n", node->type); - return NULL; + xmlFreeDoc(xmldoc); + + if (!validated) + { + WARN("no DTD or schema found\n"); + err_code = E_XML_NODTD; + hr = S_FALSE; } - hr = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMNode, (LPVOID*)&ret); - IUnknown_Release(pUnk); - if(FAILED(hr)) return NULL; - return ret; + if (err) + *err = create_parseError(err_code, NULL, NULL, NULL, 0, 0, 0); + + return hr; +} + +/* The only use case for this for loading documents. Original document node is preserved, + together with its properties, and unlinked owned nodes. Current children nodes are + unlinked, and replaced with children from the source. Such pattern makes sense only + for document nodes. The key feature is to preserved owned unlinked nodes. */ +void node_move_children(struct domnode *dest, struct domnode *src) +{ + struct domnode *child, *next; + + domnode_unlink_children(dest); + + LIST_FOR_EACH_ENTRY_SAFE(child, next, &src->children, struct domnode, entry) + { + domnode_append_child(dest, child); + } } diff --git a/dlls/msxml3/nodelist.c b/dlls/msxml3/nodelist.c index 4553253178d..0ce4dac5207 100644 --- a/dlls/msxml3/nodelist.c +++ b/dlls/msxml3/nodelist.c @@ -21,8 +21,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> #include "windef.h" #include "winbase.h" @@ -50,9 +48,9 @@ typedef struct { DispatchEx dispex; IXMLDOMNodeList IXMLDOMNodeList_iface; - LONG ref; - xmlNodePtr parent; - xmlNodePtr current; + LONG refcount; + struct domnode *parent; + struct domnode *current; IEnumVARIANT *enumvariant; } xmlnodelist; @@ -72,14 +70,11 @@ static inline xmlnodelist *impl_from_IXMLDOMNodeList( IXMLDOMNodeList *iface ) return CONTAINING_RECORD(iface, xmlnodelist, IXMLDOMNodeList_iface); } -static HRESULT WINAPI xmlnodelist_QueryInterface( - IXMLDOMNodeList *iface, - REFIID riid, - void** ppvObject ) +static HRESULT WINAPI xmlnodelist_QueryInterface(IXMLDOMNodeList *iface, REFIID riid, void **ppvObject) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); + xmlnodelist *list = impl_from_IXMLDOMNodeList(iface); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), ppvObject); if ( IsEqualGUID( riid, &IID_IUnknown ) || IsEqualGUID( riid, &IID_IDispatch ) || @@ -89,15 +84,15 @@ static HRESULT WINAPI xmlnodelist_QueryInterface( } else if (IsEqualGUID( riid, &IID_IEnumVARIANT )) { - if (!This->enumvariant) + if (!list->enumvariant) { - HRESULT hr = create_enumvariant((IUnknown*)iface, FALSE, &nodelist_enumvariant, &This->enumvariant); + HRESULT hr = create_enumvariant((IUnknown*)iface, FALSE, &nodelist_enumvariant, &list->enumvariant); if (FAILED(hr)) return hr; } - return IEnumVARIANT_QueryInterface(This->enumvariant, &IID_IEnumVARIANT, ppvObject); + return IEnumVARIANT_QueryInterface(list->enumvariant, &IID_IEnumVARIANT, ppvObject); } - else if (dispex_query_interface(&This->dispex, riid, ppvObject)) + else if (dispex_query_interface(&list->dispex, riid, ppvObject)) { return *ppvObject ? S_OK : E_NOINTERFACE; } @@ -108,181 +103,161 @@ static HRESULT WINAPI xmlnodelist_QueryInterface( return E_NOINTERFACE; } - IXMLDOMNodeList_AddRef( iface ); + IXMLDOMNodeList_AddRef(iface); return S_OK; } -static ULONG WINAPI xmlnodelist_AddRef( - IXMLDOMNodeList *iface ) +static ULONG WINAPI xmlnodelist_AddRef(IXMLDOMNodeList *iface) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); - ULONG ref = InterlockedIncrement( &This->ref ); - TRACE("%p, refcount %lu.\n", iface, ref); - return ref; + xmlnodelist *list = impl_from_IXMLDOMNodeList(iface); + ULONG refcount = InterlockedIncrement(&list->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); + + return refcount; } -static ULONG WINAPI xmlnodelist_Release( - IXMLDOMNodeList *iface ) +static void xmlnode_list_release_current(xmlnodelist *list) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); - ULONG ref = InterlockedDecrement( &This->ref ); + if (list->current && list->current != list->parent) + domnode_release(list->current); + list->current = NULL; +} - TRACE("%p, refcount %lu.\n", iface, ref); +static ULONG WINAPI xmlnodelist_Release(IXMLDOMNodeList *iface) +{ + xmlnodelist *list = impl_from_IXMLDOMNodeList(iface); + ULONG refcount = InterlockedDecrement(&list->refcount); - if (!ref) + TRACE("%p, refcount %lu.\n", iface, refcount); + + if (!refcount) { - xmldoc_release( This->parent->doc ); - if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant); - free( This ); + xmlnode_list_release_current(list); + domnode_release(list->parent); + if (list->enumvariant) IEnumVARIANT_Release(list->enumvariant); + free(list); } - return ref; + return refcount; } -static HRESULT WINAPI xmlnodelist_GetTypeInfoCount( - IXMLDOMNodeList *iface, - UINT* pctinfo ) +static HRESULT WINAPI xmlnodelist_GetTypeInfoCount(IXMLDOMNodeList *iface, UINT *count) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); + xmlnodelist *list = impl_from_IXMLDOMNodeList(iface); + return IDispatchEx_GetTypeInfoCount(&list->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI xmlnodelist_GetTypeInfo( - IXMLDOMNodeList *iface, - UINT iTInfo, - LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI xmlnodelist_GetTypeInfo(IXMLDOMNodeList *iface, UINT index, LCID lcid, ITypeInfo **ti) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + xmlnodelist *list = impl_from_IXMLDOMNodeList(iface); + return IDispatchEx_GetTypeInfo(&list->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI xmlnodelist_GetIDsOfNames( - IXMLDOMNodeList *iface, - REFIID riid, - LPOLESTR* rgszNames, - UINT cNames, - LCID lcid, - DISPID* rgDispId ) +static HRESULT WINAPI xmlnodelist_GetIDsOfNames(IXMLDOMNodeList *iface, REFIID riid, + LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, + xmlnodelist *list = impl_from_IXMLDOMNodeList(iface); + return IDispatchEx_GetIDsOfNames(&list->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); } -static HRESULT WINAPI xmlnodelist_Invoke( - IXMLDOMNodeList *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS* pDispParams, - VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, - UINT* puArgErr ) +static HRESULT WINAPI xmlnodelist_Invoke(IXMLDOMNodeList *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, + EXCEPINFO *ei, UINT *puArgErr) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + xmlnodelist *list = impl_from_IXMLDOMNodeList(iface); + return IDispatchEx_Invoke(&list->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + flags, params, result, ei, puArgErr); } -static HRESULT WINAPI xmlnodelist_get_item( - IXMLDOMNodeList* iface, - LONG index, - IXMLDOMNode** listItem) +static HRESULT WINAPI xmlnodelist_get_item(IXMLDOMNodeList *iface, LONG index, IXMLDOMNode **node) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); - xmlNodePtr curr; - LONG nodeIndex = 0; + xmlnodelist *list = impl_from_IXMLDOMNodeList(iface); + struct list *p; + LONG i = 0; - TRACE("%p, %ld, %p.\n", iface, index, listItem); + TRACE("%p, %ld, %p.\n", iface, index, node); - if(!listItem) + if (!node) return E_INVALIDARG; - *listItem = NULL; + *node = NULL; if (index < 0) return S_FALSE; - curr = This->parent->children; - while(curr) + p = list_head(&list->parent->children); + while (p) { - if(nodeIndex++ == index) break; - curr = curr->next; + if (i++ == index) break; + p = list_next(&list->parent->children, p); } - if(!curr) return S_FALSE; - - *listItem = create_node( curr ); + if (!p) + return S_FALSE; - return S_OK; + return create_node(LIST_ENTRY(p, struct domnode, entry), node); } -static HRESULT WINAPI xmlnodelist_get_length( - IXMLDOMNodeList* iface, - LONG* listLength) +static HRESULT WINAPI xmlnodelist_get_length(IXMLDOMNodeList *iface, LONG *length) { + xmlnodelist *list = impl_from_IXMLDOMNodeList(iface); - xmlNodePtr curr; - LONG nodeCount = 0; - - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); - - TRACE("(%p)->(%p)\n", This, listLength); + TRACE("%p, %p.\n", iface, length); - if(!listLength) + if (!length) return E_INVALIDARG; - curr = This->parent->children; - while (curr) - { - nodeCount++; - curr = curr->next; - } - - *listLength = nodeCount; + *length = list_count(&list->parent->children); return S_OK; } -static HRESULT WINAPI xmlnodelist_nextNode( - IXMLDOMNodeList* iface, - IXMLDOMNode** nextItem) +static HRESULT WINAPI xmlnodelist_nextNode(IXMLDOMNodeList *iface, IXMLDOMNode **node) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); + xmlnodelist *list = impl_from_IXMLDOMNodeList(iface); + HRESULT hr; - TRACE("(%p)->(%p)\n", This, nextItem ); + TRACE("%p, %p.\n", iface, node); - if(!nextItem) + if (!node) return E_INVALIDARG; - *nextItem = NULL; + *node = NULL; - if (!This->current) + /* First iteration */ + if (list->current == list->parent) + { + list->current = domnode_get_first_child(list->parent); + if (list->current) domnode_addref(list->current); + } + + if (!list->current) return S_FALSE; - *nextItem = create_node( This->current ); - This->current = This->current->next; - return S_OK; + hr = create_node(list->current, node); + domnode_release(list->current); + list->current = domnode_get_next_sibling(list->current); + if (list->current) domnode_addref(list->current); + + return hr; } -static HRESULT WINAPI xmlnodelist_reset( - IXMLDOMNodeList* iface) +static HRESULT WINAPI xmlnodelist_reset(IXMLDOMNodeList *iface) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); + xmlnodelist *list = impl_from_IXMLDOMNodeList(iface); + + TRACE("%p.\n", iface); - TRACE("%p\n", This); - This->current = This->parent->children; + xmlnode_list_release_current(list); + list->current = list->parent; return S_OK; } -static HRESULT WINAPI xmlnodelist__newEnum( - IXMLDOMNodeList* iface, - IUnknown** enumv) +static HRESULT WINAPI xmlnodelist__newEnum(IXMLDOMNodeList *iface, IUnknown **enumv) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( iface ); - TRACE("(%p)->(%p)\n", This, enumv); + TRACE("%p, %p.\n", iface, enumv); + return create_enumvariant((IUnknown*)iface, TRUE, &nodelist_enumvariant, (IEnumVARIANT**)enumv); } @@ -320,7 +295,7 @@ static HRESULT xmlnodelist_get_dispid(IUnknown *iface, BSTR name, DWORD flags, D static HRESULT xmlnodelist_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei) { - xmlnodelist *This = impl_from_IXMLDOMNodeList( (IXMLDOMNodeList*)iface ); + xmlnodelist *list = impl_from_IXMLDOMNodeList((IXMLDOMNodeList *)iface); TRACE("%p, %ld, %lx, %x, %p, %p, %p.\n", iface, id, lcid, flags, params, res, ei); @@ -333,7 +308,7 @@ static HRESULT xmlnodelist_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fl IXMLDOMNode *disp = NULL; V_VT(res) = VT_DISPATCH; - IXMLDOMNodeList_get_item(&This->IXMLDOMNodeList_iface, id - DISPID_DOM_COLLECTION_BASE, &disp); + IXMLDOMNodeList_get_item(&list->IXMLDOMNodeList_iface, id - DISPID_DOM_COLLECTION_BASE, &disp); V_DISPATCH(res) = (IDispatch*)disp; break; } @@ -366,7 +341,7 @@ static HRESULT xmlnodelist_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fl return hr; } - IXMLDOMNodeList_get_item(&This->IXMLDOMNodeList_iface, V_I4(&index), &item); + IXMLDOMNodeList_get_item(&list->IXMLDOMNodeList_iface, V_I4(&index), &item); V_VT(res) = VT_DISPATCH; V_DISPATCH(res) = (IDispatch*)item; break; @@ -386,38 +361,40 @@ static HRESULT xmlnodelist_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fl return S_OK; } -static const dispex_static_data_vtbl_t xmlnodelist_dispex_vtbl = { +static const dispex_static_data_vtbl_t xmlnodelist_dispex_vtbl = +{ xmlnodelist_get_dispid, xmlnodelist_invoke }; -static const tid_t xmlnodelist_iface_tids[] = { +static const tid_t xmlnodelist_iface_tids[] = +{ IXMLDOMNodeList_tid, 0 }; -static dispex_static_data_t xmlnodelist_dispex = { + +static dispex_static_data_t xmlnodelist_dispex = +{ &xmlnodelist_dispex_vtbl, IXMLDOMNodeList_tid, NULL, xmlnodelist_iface_tids }; -IXMLDOMNodeList* create_children_nodelist( xmlNodePtr node ) +HRESULT create_children_nodelist(struct domnode *node, IXMLDOMNodeList **list) { - xmlnodelist *This; + xmlnodelist *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; - This = malloc(sizeof(*This)); - if ( !This ) - return NULL; + object->IXMLDOMNodeList_iface.lpVtbl = &xmlnodelist_vtbl; + object->refcount = 1; + object->current = object->parent = domnode_addref(node); - This->IXMLDOMNodeList_iface.lpVtbl = &xmlnodelist_vtbl; - This->ref = 1; - This->parent = node; - This->current = node->children; - This->enumvariant = NULL; - xmldoc_add_ref( node->doc ); + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMNodeList_iface, &xmlnodelist_dispex); - init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNodeList_iface, &xmlnodelist_dispex); + *list = &object->IXMLDOMNodeList_iface; - return &This->IXMLDOMNodeList_iface; + return S_OK; } diff --git a/dlls/msxml3/nodemap.c b/dlls/msxml3/nodemap.c index ca8d0557465..419dfa6305d 100644 --- a/dlls/msxml3/nodemap.c +++ b/dlls/msxml3/nodemap.c @@ -21,8 +21,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> #include "windef.h" #include "winbase.h" @@ -43,9 +41,9 @@ typedef struct DispatchEx dispex; IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface; ISupportErrorInfo ISupportErrorInfo_iface; - LONG ref; + LONG refcount; - xmlNodePtr node; + struct domnode *node; LONG iterator; IEnumVARIANT *enumvariant; @@ -73,41 +71,40 @@ static inline xmlnodemap *impl_from_ISupportErrorInfo( ISupportErrorInfo *iface return CONTAINING_RECORD(iface, xmlnodemap, ISupportErrorInfo_iface); } -static HRESULT WINAPI xmlnodemap_QueryInterface( - IXMLDOMNamedNodeMap *iface, - REFIID riid, void** ppvObject ) +static HRESULT WINAPI xmlnodemap_QueryInterface(IXMLDOMNamedNodeMap *iface, REFIID riid, void **obj) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); - if( IsEqualGUID( riid, &IID_IUnknown ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IXMLDOMNamedNodeMap ) ) + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + if (IsEqualGUID( riid, &IID_IUnknown) || + IsEqualGUID( riid, &IID_IDispatch) || + IsEqualGUID( riid, &IID_IXMLDOMNamedNodeMap)) { - *ppvObject = iface; + *obj = iface; } - else if (IsEqualGUID( riid, &IID_IEnumVARIANT )) + else if (IsEqualGUID(riid, &IID_IEnumVARIANT)) { - if (!This->enumvariant) + if (!map->enumvariant) { - HRESULT hr = create_enumvariant((IUnknown*)iface, FALSE, &nodemap_enumvariant, &This->enumvariant); + HRESULT hr = create_enumvariant((IUnknown*)iface, FALSE, &nodemap_enumvariant, &map->enumvariant); if (FAILED(hr)) return hr; } - return IEnumVARIANT_QueryInterface(This->enumvariant, &IID_IEnumVARIANT, ppvObject); + return IEnumVARIANT_QueryInterface(map->enumvariant, &IID_IEnumVARIANT, obj); } - else if (dispex_query_interface(&This->dispex, riid, ppvObject)) + else if (dispex_query_interface(&map->dispex, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } - else if( IsEqualGUID( riid, &IID_ISupportErrorInfo )) + else if (IsEqualGUID( riid, &IID_ISupportErrorInfo)) { - *ppvObject = &This->ISupportErrorInfo_iface; + *obj = &map->ISupportErrorInfo_iface; } else { TRACE("interface %s not implemented\n", debugstr_guid(riid)); - *ppvObject = NULL; + *obj = NULL; return E_NOINTERFACE; } @@ -116,188 +113,150 @@ static HRESULT WINAPI xmlnodemap_QueryInterface( return S_OK; } -static ULONG WINAPI xmlnodemap_AddRef( - IXMLDOMNamedNodeMap *iface ) +static ULONG WINAPI xmlnodemap_AddRef(IXMLDOMNamedNodeMap *iface) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - ULONG ref = InterlockedIncrement( &This->ref ); - TRACE("%p, refcount %lu.\n", iface, ref); - return ref; + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); + ULONG refcount = InterlockedIncrement(&map->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); + + return refcount; } -static ULONG WINAPI xmlnodemap_Release( - IXMLDOMNamedNodeMap *iface ) +static ULONG WINAPI xmlnodemap_Release(IXMLDOMNamedNodeMap *iface) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - ULONG ref = InterlockedDecrement( &This->ref ); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); + ULONG refcount = InterlockedDecrement(&map->refcount); - TRACE("%p, refcount %lu.\n", iface, ref); + TRACE("%p, refcount %lu.\n", iface, refcount); - if (!ref) + if (!refcount) { - xmlnode_release( This->node ); - xmldoc_release( This->node->doc ); - if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant); - free( This ); + domnode_release(map->node); + if (map->enumvariant) + IEnumVARIANT_Release(map->enumvariant); + free(map); } - return ref; + return refcount; } -static HRESULT WINAPI xmlnodemap_GetTypeInfoCount( - IXMLDOMNamedNodeMap *iface, - UINT* pctinfo ) +static HRESULT WINAPI xmlnodemap_GetTypeInfoCount(IXMLDOMNamedNodeMap *iface, UINT *count) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); + return IDispatchEx_GetTypeInfoCount(&map->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI xmlnodemap_GetTypeInfo( - IXMLDOMNamedNodeMap *iface, - UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI xmlnodemap_GetTypeInfo(IXMLDOMNamedNodeMap *iface, UINT index, LCID lcid, ITypeInfo **ti) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); + return IDispatchEx_GetTypeInfo(&map->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI xmlnodemap_GetIDsOfNames( - IXMLDOMNamedNodeMap *iface, - REFIID riid, LPOLESTR* rgszNames, - UINT cNames, LCID lcid, DISPID* rgDispId ) +static HRESULT WINAPI xmlnodemap_GetIDsOfNames(IXMLDOMNamedNodeMap *iface, REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, - riid, rgszNames, cNames, lcid, rgDispId); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); + return IDispatchEx_GetIDsOfNames(&map->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); } -static HRESULT WINAPI xmlnodemap_Invoke( - IXMLDOMNamedNodeMap *iface, - DISPID dispIdMember, REFIID riid, LCID lcid, - WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr ) +static HRESULT WINAPI xmlnodemap_Invoke(IXMLDOMNamedNodeMap *iface, DISPID dispIdMember, REFIID riid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *puArgErr) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); + return IDispatchEx_Invoke(&map->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, flags, params, result, ei, puArgErr); } -static HRESULT WINAPI xmlnodemap_getNamedItem( - IXMLDOMNamedNodeMap *iface, - BSTR name, - IXMLDOMNode** item) +static HRESULT WINAPI xmlnodemap_getNamedItem(IXMLDOMNamedNodeMap *iface, BSTR name, IXMLDOMNode **item) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), item ); + TRACE("%p, %s, %p.\n", iface, debugstr_w(name), item); - return This->funcs->get_named_item(This->node, name, item); + return map->funcs->get_named_item(map->node, name, item); } -static HRESULT WINAPI xmlnodemap_setNamedItem( - IXMLDOMNamedNodeMap *iface, - IXMLDOMNode* newItem, - IXMLDOMNode** namedItem) +static HRESULT WINAPI xmlnodemap_setNamedItem(IXMLDOMNamedNodeMap *iface, IXMLDOMNode *newItem, IXMLDOMNode **namedItem) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); - TRACE("(%p)->(%p %p)\n", This, newItem, namedItem ); + TRACE("%p, %p, %p.\n", iface, newItem, namedItem ); - return This->funcs->set_named_item(This->node, newItem, namedItem); + return map->funcs->set_named_item(map->node, newItem, namedItem); } -static HRESULT WINAPI xmlnodemap_removeNamedItem( - IXMLDOMNamedNodeMap *iface, - BSTR name, - IXMLDOMNode** namedItem) +static HRESULT WINAPI xmlnodemap_removeNamedItem(IXMLDOMNamedNodeMap *iface, BSTR name, IXMLDOMNode **namedItem) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), namedItem ); + TRACE("%p, %s, %p.\n", iface, debugstr_w(name), namedItem); - return This->funcs->remove_named_item(This->node, name, namedItem); + return map->funcs->remove_named_item(map->node, name, namedItem); } -static HRESULT WINAPI xmlnodemap_get_item( - IXMLDOMNamedNodeMap *iface, - LONG index, - IXMLDOMNode** item) +static HRESULT WINAPI xmlnodemap_get_item(IXMLDOMNamedNodeMap *iface, LONG index, IXMLDOMNode **item) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); TRACE("%p, %ld, %p.\n", iface, index, item); - return This->funcs->get_item(This->node, index, item); + return map->funcs->get_item(map->node, index, item); } -static HRESULT WINAPI xmlnodemap_get_length( - IXMLDOMNamedNodeMap *iface, - LONG *length) +static HRESULT WINAPI xmlnodemap_get_length(IXMLDOMNamedNodeMap *iface, LONG *length) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); - TRACE("(%p)->(%p)\n", This, length); + TRACE("%p, %p.\n", iface, length); - return This->funcs->get_length(This->node, length); + return map->funcs->get_length(map->node, length); } -static HRESULT WINAPI xmlnodemap_getQualifiedItem( - IXMLDOMNamedNodeMap *iface, - BSTR baseName, - BSTR namespaceURI, - IXMLDOMNode** item) +static HRESULT WINAPI xmlnodemap_getQualifiedItem(IXMLDOMNamedNodeMap *iface, + BSTR baseName, BSTR namespaceURI, IXMLDOMNode **item) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); - TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), item); + TRACE("%p, %s, %s, %p.\n", iface, debugstr_w(baseName), debugstr_w(namespaceURI), item); - return This->funcs->get_qualified_item(This->node, baseName, namespaceURI, item); + return map->funcs->get_qualified_item(map->node, baseName, namespaceURI, item); } -static HRESULT WINAPI xmlnodemap_removeQualifiedItem( - IXMLDOMNamedNodeMap *iface, - BSTR baseName, - BSTR namespaceURI, - IXMLDOMNode** item) +static HRESULT WINAPI xmlnodemap_removeQualifiedItem(IXMLDOMNamedNodeMap *iface, BSTR baseName, + BSTR namespaceURI, IXMLDOMNode **item) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); - TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), item); + TRACE("%p, %s, %s, %p.\n", iface, debugstr_w(baseName), debugstr_w(namespaceURI), item); - return This->funcs->remove_qualified_item(This->node, baseName, namespaceURI, item); + return map->funcs->remove_qualified_item(map->node, baseName, namespaceURI, item); } -static HRESULT WINAPI xmlnodemap_nextNode( - IXMLDOMNamedNodeMap *iface, - IXMLDOMNode** nextItem) +static HRESULT WINAPI xmlnodemap_nextNode(IXMLDOMNamedNodeMap *iface, IXMLDOMNode **nextItem) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); - TRACE("%p, %p, %ld.\n", iface, nextItem, This->iterator); + TRACE("%p, %p, %ld.\n", iface, nextItem, map->iterator); - return This->funcs->next_node(This->node, &This->iterator, nextItem); + return map->funcs->next_node(map->node, &map->iterator, nextItem); } -static HRESULT WINAPI xmlnodemap_reset( - IXMLDOMNamedNodeMap *iface ) +static HRESULT WINAPI xmlnodemap_reset(IXMLDOMNamedNodeMap *iface) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap(iface); - TRACE("%p, %ld.\n", iface, This->iterator); + TRACE("%p, %ld.\n", iface, map->iterator); - This->iterator = 0; + map->iterator = 0; return S_OK; } -static HRESULT WINAPI xmlnodemap__newEnum( - IXMLDOMNamedNodeMap *iface, - IUnknown** enumv) +static HRESULT WINAPI xmlnodemap__newEnum(IXMLDOMNamedNodeMap *iface, IUnknown **enumv) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - TRACE("(%p)->(%p)\n", This, enumv); - return create_enumvariant((IUnknown*)iface, TRUE, &nodemap_enumvariant, (IEnumVARIANT**)enumv); + TRACE("%p, %p.\n", iface, enumv); + + return create_enumvariant((IUnknown *)iface, TRUE, &nodemap_enumvariant, (IEnumVARIANT **)enumv); } static const struct IXMLDOMNamedNodeMapVtbl XMLDOMNamedNodeMapVtbl = @@ -321,9 +280,7 @@ static const struct IXMLDOMNamedNodeMapVtbl XMLDOMNamedNodeMapVtbl = xmlnodemap__newEnum, }; -static HRESULT WINAPI support_error_QueryInterface( - ISupportErrorInfo *iface, - REFIID riid, void** ppvObject ) +static HRESULT WINAPI support_error_QueryInterface(ISupportErrorInfo *iface, REFIID riid, void** ppvObject ) { xmlnodemap *This = impl_from_ISupportErrorInfo( iface ); TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); @@ -379,7 +336,7 @@ static HRESULT xmlnodemap_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DI static HRESULT xmlnodemap_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei) { - xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( (IXMLDOMNamedNodeMap*)iface ); + xmlnodemap *map = impl_from_IXMLDOMNamedNodeMap((IXMLDOMNamedNodeMap *)iface); TRACE("%p, %ld, %lx, %x, %p, %p, %p.\n", iface, id, lcid, flags, params, res, ei); @@ -395,7 +352,7 @@ static HRESULT xmlnodemap_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fla { IXMLDOMNode *disp = NULL; - IXMLDOMNamedNodeMap_get_item(&This->IXMLDOMNamedNodeMap_iface, id - DISPID_DOM_COLLECTION_BASE, &disp); + IXMLDOMNamedNodeMap_get_item(&map->IXMLDOMNamedNodeMap_iface, id - DISPID_DOM_COLLECTION_BASE, &disp); V_DISPATCH(res) = (IDispatch*)disp; break; } @@ -411,43 +368,44 @@ static HRESULT xmlnodemap_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fla return S_OK; } -static const dispex_static_data_vtbl_t xmlnodemap_dispex_vtbl = { +static const dispex_static_data_vtbl_t xmlnodemap_dispex_vtbl = +{ xmlnodemap_get_dispid, xmlnodemap_invoke }; -static const tid_t xmlnodemap_iface_tids[] = { +static const tid_t xmlnodemap_iface_tids[] = +{ IXMLDOMNamedNodeMap_tid, 0 }; -static dispex_static_data_t xmlnodemap_dispex = { +static dispex_static_data_t xmlnodemap_dispex = +{ &xmlnodemap_dispex_vtbl, IXMLDOMNamedNodeMap_tid, NULL, xmlnodemap_iface_tids }; -IXMLDOMNamedNodeMap *create_nodemap(xmlNodePtr node, const struct nodemap_funcs *funcs) +HRESULT create_nodemap(struct domnode *node, const struct nodemap_funcs *funcs, IXMLDOMNamedNodeMap **map) { - xmlnodemap *This; + xmlnodemap *object; - This = malloc(sizeof(*This)); - if ( !This ) - return NULL; + *map = NULL; - This->IXMLDOMNamedNodeMap_iface.lpVtbl = &XMLDOMNamedNodeMapVtbl; - This->ISupportErrorInfo_iface.lpVtbl = &SupportErrorInfoVtbl; - This->node = node; - This->ref = 1; - This->iterator = 0; - This->enumvariant = NULL; - This->funcs = funcs; + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; - init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex); + object->IXMLDOMNamedNodeMap_iface.lpVtbl = &XMLDOMNamedNodeMapVtbl; + object->ISupportErrorInfo_iface.lpVtbl = &SupportErrorInfoVtbl; + object->refcount = 1; + object->funcs = funcs; + object->node = domnode_addref(node); - xmlnode_add_ref(node); - xmldoc_add_ref(node->doc); + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex); - return &This->IXMLDOMNamedNodeMap_iface; + *map = &object->IXMLDOMNamedNodeMap_iface; + + return S_OK; } diff --git a/dlls/msxml3/pi.c b/dlls/msxml3/pi.c index e37cf644f1b..6f98218f108 100644 --- a/dlls/msxml3/pi.c +++ b/dlls/msxml3/pi.c @@ -21,8 +21,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> #include "windef.h" #include "winbase.h" @@ -39,14 +37,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); typedef struct _dom_pi { - xmlnode node; + DispatchEx dispex; IXMLDOMProcessingInstruction IXMLDOMProcessingInstruction_iface; - LONG ref; + LONG refcount; + struct domnode *node; } dom_pi; static const struct nodemap_funcs dom_pi_attr_map; -static const tid_t dompi_se_tids[] = { +static const tid_t dompi_se_tids[] = +{ IXMLDOMNode_tid, IXMLDOMProcessingInstruction_tid, NULL_tid @@ -57,81 +57,78 @@ static inline dom_pi *impl_from_IXMLDOMProcessingInstruction( IXMLDOMProcessingI return CONTAINING_RECORD(iface, dom_pi, IXMLDOMProcessingInstruction_iface); } -static HRESULT WINAPI dom_pi_QueryInterface( - IXMLDOMProcessingInstruction *iface, - REFIID riid, - void** ppvObject ) +static HRESULT WINAPI dom_pi_QueryInterface(IXMLDOMProcessingInstruction *iface, REFIID riid, void **obj) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); - if ( IsEqualGUID( riid, &IID_IXMLDOMProcessingInstruction ) || - IsEqualGUID( riid, &IID_IXMLDOMNode ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IUnknown ) ) + if (IsEqualGUID(riid, &IID_IXMLDOMProcessingInstruction) || + IsEqualGUID(riid, &IID_IXMLDOMNode) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IUnknown)) { - *ppvObject = iface; + *obj = iface; } - else if(node_query_interface(&This->node, riid, ppvObject)) + else if (dispex_query_interface(&pi->dispex, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } - else if(IsEqualGUID( riid, &IID_ISupportErrorInfo )) + else if (node_query_interface(pi->node, riid, obj)) { - return node_create_supporterrorinfo(dompi_se_tids, ppvObject); + return *obj ? S_OK : E_NOINTERFACE; + } + else if (IsEqualGUID(riid, &IID_ISupportErrorInfo)) + { + return node_create_supporterrorinfo(dompi_se_tids, obj); } else { TRACE("Unsupported interface %s\n", debugstr_guid(riid)); - *ppvObject = NULL; + *obj = NULL; return E_NOINTERFACE; } - IUnknown_AddRef((IUnknown*)*ppvObject); + IUnknown_AddRef((IUnknown *)*obj); return S_OK; } -static ULONG WINAPI dom_pi_AddRef( - IXMLDOMProcessingInstruction *iface ) +static ULONG WINAPI dom_pi_AddRef(IXMLDOMProcessingInstruction *iface) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - ULONG ref = InterlockedIncrement( &This->ref ); - TRACE("%p, refcount %lu.\n", iface, ref); - return ref; + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); + ULONG refcount = InterlockedIncrement(&pi->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); + + return refcount; } -static ULONG WINAPI dom_pi_Release( - IXMLDOMProcessingInstruction *iface ) +static ULONG WINAPI dom_pi_Release(IXMLDOMProcessingInstruction *iface) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - ULONG ref = InterlockedDecrement( &This->ref ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); + ULONG refcount = InterlockedDecrement(&pi->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); - TRACE("%p, refcount %lu.\n", iface, ref); - if ( ref == 0 ) + if (!refcount) { - destroy_xmlnode(&This->node); - free(This); + domnode_release(pi->node); + free(pi); } - return ref; + return refcount; } -static HRESULT WINAPI dom_pi_GetTypeInfoCount( - IXMLDOMProcessingInstruction *iface, - UINT* pctinfo ) +static HRESULT WINAPI dom_pi_GetTypeInfoCount(IXMLDOMProcessingInstruction *iface, UINT *count) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); + return IDispatchEx_GetTypeInfoCount(&pi->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI dom_pi_GetTypeInfo( - IXMLDOMProcessingInstruction *iface, - UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI dom_pi_GetTypeInfo(IXMLDOMProcessingInstruction *iface, UINT index, LCID lcid, ITypeInfo **ti) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); + return IDispatchEx_GetTypeInfo(&pi->dispex.IDispatchEx_iface, index, lcid, ti); } static HRESULT WINAPI dom_pi_GetIDsOfNames( @@ -139,8 +136,8 @@ static HRESULT WINAPI dom_pi_GetIDsOfNames( REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId ) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); + return IDispatchEx_GetIDsOfNames(&pi->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); } @@ -150,623 +147,354 @@ static HRESULT WINAPI dom_pi_Invoke( WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr ) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); + return IDispatchEx_Invoke(&pi->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); } -static HRESULT WINAPI dom_pi_get_nodeName( - IXMLDOMProcessingInstruction *iface, - BSTR* p ) +static HRESULT WINAPI dom_pi_get_nodeName(IXMLDOMProcessingInstruction *iface, BSTR *p) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_nodeName(&This->node, p); + return node_get_name(pi->node, p); } -static HRESULT WINAPI dom_pi_get_nodeValue( - IXMLDOMProcessingInstruction *iface, - VARIANT* value) +static HRESULT WINAPI dom_pi_get_nodeValue(IXMLDOMProcessingInstruction *iface, VARIANT *value) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - TRACE("(%p)->(%p)\n", This, value); + TRACE("%p, %p.\n", iface, value); - return node_get_content(&This->node, value); + return node_get_value(pi->node, value); } -static HRESULT WINAPI dom_pi_put_nodeValue( - IXMLDOMProcessingInstruction *iface, - VARIANT value) +static HRESULT WINAPI dom_pi_put_nodeValue(IXMLDOMProcessingInstruction *iface, VARIANT value) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - BSTR target; - HRESULT hr; - - TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - /* Cannot set data to a PI node whose target is 'xml' */ - hr = IXMLDOMProcessingInstruction_get_nodeName(iface, &target); - if(hr == S_OK) - { - if(!wcscmp(target, L"xml")) - { - SysFreeString(target); - return E_FAIL; - } - - SysFreeString(target); - } + TRACE("%p, %s.\n", iface, debugstr_variant(&value)); - return node_put_value(&This->node, &value); + return node_put_value(pi->node, &value); } -static HRESULT WINAPI dom_pi_get_nodeType( - IXMLDOMProcessingInstruction *iface, - DOMNodeType* domNodeType ) +static HRESULT WINAPI dom_pi_get_nodeType(IXMLDOMProcessingInstruction *iface, DOMNodeType *type) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - - TRACE("(%p)->(%p)\n", This, domNodeType); + TRACE("%p, %p.\n", iface, type); - *domNodeType = NODE_PROCESSING_INSTRUCTION; + *type = NODE_PROCESSING_INSTRUCTION; return S_OK; } -static HRESULT WINAPI dom_pi_get_parentNode( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode** parent ) +static HRESULT WINAPI dom_pi_get_parentNode(IXMLDOMProcessingInstruction *iface, IXMLDOMNode **parent) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - TRACE("(%p)->(%p)\n", This, parent); + TRACE("%p, %p.\n", iface, parent); - return node_get_parent(&This->node, parent); + return node_get_parent(pi->node, parent); } -static HRESULT WINAPI dom_pi_get_childNodes( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNodeList** outList) +static HRESULT WINAPI dom_pi_get_childNodes(IXMLDOMProcessingInstruction *iface, IXMLDOMNodeList **list) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p)\n", This, outList); + TRACE("%p, %p.\n", iface, list); - return node_get_child_nodes(&This->node, outList); + return node_get_child_nodes(pi->node, list); } -static HRESULT WINAPI dom_pi_get_firstChild( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI dom_pi_get_firstChild(IXMLDOMProcessingInstruction *iface, IXMLDOMNode **node) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + TRACE("%p, %p.\n", iface, node); - TRACE("(%p)->(%p)\n", This, domNode); - - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI dom_pi_get_lastChild( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI dom_pi_get_lastChild(IXMLDOMProcessingInstruction *iface, IXMLDOMNode **node) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI dom_pi_get_previousSibling( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI dom_pi_get_previousSibling(IXMLDOMProcessingInstruction *iface, IXMLDOMNode **node) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_previous_sibling(&This->node, domNode); + return node_get_previous_sibling(pi->node, node); } -static HRESULT WINAPI dom_pi_get_nextSibling( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI dom_pi_get_nextSibling(IXMLDOMProcessingInstruction *iface, IXMLDOMNode **node) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_next_sibling(&This->node, domNode); + return node_get_next_sibling(pi->node, node); } -static HRESULT xml_get_value(xmlChar **p, xmlChar **value) +static HRESULT WINAPI dom_pi_get_attributes(IXMLDOMProcessingInstruction *iface, IXMLDOMNamedNodeMap **map) { - xmlChar *v, q; - int len; - - while (isspace(**p)) *p += 1; - if (**p != '=') return XML_E_MISSINGEQUALS; - *p += 1; + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - while (isspace(**p)) *p += 1; - if (**p != '"' && **p != '\'') return XML_E_MISSINGQUOTE; - q = **p; - *p += 1; - - v = *p; - while (**p && **p != q) *p += 1; - if (!**p) return XML_E_BADCHARINSTRING; - len = *p - v; - if (!len) return XML_E_MISSINGNAME; - *p += 1; - - *value = malloc(len + 1); - if (!*value) return E_OUTOFMEMORY; - memcpy(*value, v, len); - *(*value + len) = 0; - - return S_OK; -} + TRACE("%p, %p.\n", iface, map); -static void set_prop(xmlNodePtr node, xmlAttrPtr attr) -{ - xmlAttrPtr prop; + if (!map) return E_INVALIDARG; - if (!node->properties) + if (!wcscmp(pi->node->name, L"xml")) { - node->properties = attr; - return; + return create_nodemap(pi->node, &dom_pi_attr_map, map); + } + else + { + *map = NULL; + return S_FALSE; } - - prop = node->properties; - while (prop->next) prop = prop->next; - - prop->next = attr; } -static HRESULT parse_xml_decl(xmlNodePtr node) +static HRESULT WINAPI dom_pi_insertBefore(IXMLDOMProcessingInstruction *iface, IXMLDOMNode *newNode, VARIANT refChild, + IXMLDOMNode** outOldNode) { - xmlChar *version, *encoding, *standalone, *p; - xmlAttrPtr attr; - HRESULT hr = S_OK; - - if (!node->content) return S_OK; - - version = encoding = standalone = NULL; + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - p = node->content; + FIXME("%p, %p, %s, %p needs test\n", iface, newNode, debugstr_variant(&refChild), outOldNode); - while (*p) - { - while (isspace(*p)) p++; - if (!*p) break; - - if (!strncmp((const char *)p, "version", 7)) - { - p += 7; - if ((hr = xml_get_value(&p, &version)) != S_OK) goto fail; - } - else if (!strncmp((const char *)p, "encoding", 8)) - { - p += 8; - if ((hr = xml_get_value(&p, &encoding)) != S_OK) goto fail; - } - else if (!strncmp((const char *)p, "standalone", 10)) - { - p += 10; - if ((hr = xml_get_value(&p, &standalone)) != S_OK) goto fail; - } - else - { - FIXME("unexpected XML attribute %s\n", debugstr_a((const char *)p)); - hr = XML_E_UNEXPECTED_ATTRIBUTE; - goto fail; - } - } + return node_insert_before(pi->node, newNode, &refChild, outOldNode); +} - /* xmlSetProp/xmlSetNsProp accept only nodes of type XML_ELEMENT_NODE, - * so we have to create and assign attributes to a node by hand. - */ +static HRESULT WINAPI dom_pi_replaceChild(IXMLDOMProcessingInstruction *iface, IXMLDOMNode *newNode, + IXMLDOMNode* oldNode, IXMLDOMNode** outOldNode) +{ + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - if (version) - { - attr = xmlSetNsProp(NULL, NULL, (const xmlChar *)"version", version); - if (attr) - { - attr->doc = node->doc; - set_prop(node, attr); - } - else hr = E_OUTOFMEMORY; - } - if (encoding) - { - attr = xmlSetNsProp(NULL, NULL, (const xmlChar *)"encoding", encoding); - if (attr) - { - attr->doc = node->doc; - set_prop(node, attr); - } - else hr = E_OUTOFMEMORY; - } - if (standalone) - { - attr = xmlSetNsProp(NULL, NULL, (const xmlChar *)"standalone", standalone); - if (attr) - { - attr->doc = node->doc; - set_prop(node, attr); - } - else hr = E_OUTOFMEMORY; - } + FIXME("%p, %p, %p, %p needs test\n", iface, newNode, oldNode, outOldNode); -fail: - if (hr != S_OK) - { - xmlFreePropList(node->properties); - node->properties = NULL; - } - - free(version); - free(encoding); - free(standalone); - return hr; + return node_replace_child(pi->node, newNode, oldNode, outOldNode); } -static HRESULT WINAPI dom_pi_get_attributes( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNamedNodeMap** map) +static HRESULT WINAPI dom_pi_removeChild(IXMLDOMProcessingInstruction *iface, IXMLDOMNode *child, IXMLDOMNode **oldChild) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - HRESULT hr; - BSTR name; - - TRACE("(%p)->(%p)\n", This, map); - - if (!map) return E_INVALIDARG; + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - *map = NULL; + TRACE("%p, %p, %p.\n", iface, child, oldChild); - hr = node_get_nodeName(&This->node, &name); - if (hr != S_OK) return hr; + return node_remove_child(pi->node, child, oldChild); +} - if (!wcscmp(name, L"xml")) - *map = create_nodemap(This->node.node, &dom_pi_attr_map); +static HRESULT WINAPI dom_pi_appendChild(IXMLDOMProcessingInstruction *iface, IXMLDOMNode *child, IXMLDOMNode **outChild) +{ + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - SysFreeString(name); + TRACE("%p, %p, %p.\n", iface, child, outChild); - return *map ? S_OK : S_FALSE; + return node_append_child(pi->node, child, outChild); } -static HRESULT WINAPI dom_pi_insertBefore( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode* newNode, VARIANT refChild, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI dom_pi_hasChildNodes(IXMLDOMProcessingInstruction *iface, VARIANT_BOOL *ret) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction( iface ); - FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode); + TRACE("%p, %p.\n", iface, ret); - return node_insert_before(&This->node, newNode, &refChild, outOldNode); + return node_has_childnodes(pi->node, ret); } -static HRESULT WINAPI dom_pi_replaceChild( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode* newNode, - IXMLDOMNode* oldNode, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI dom_pi_get_ownerDocument(IXMLDOMProcessingInstruction *iface, IXMLDOMDocument **doc) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - FIXME("(%p)->(%p %p %p) needs test\n", This, newNode, oldNode, outOldNode); + TRACE("%p, %p.\n", iface, doc); - return node_replace_child(&This->node, newNode, oldNode, outOldNode); + return node_get_owner_document(pi->node, doc); } -static HRESULT WINAPI dom_pi_removeChild( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode *child, IXMLDOMNode **oldChild) +static HRESULT WINAPI dom_pi_cloneNode(IXMLDOMProcessingInstruction *iface, VARIANT_BOOL deep, IXMLDOMNode **node) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p %p)\n", This, child, oldChild); - return node_remove_child(&This->node, child, oldChild); -} + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); -static HRESULT WINAPI dom_pi_appendChild( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode *child, IXMLDOMNode **outChild) -{ - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p %p)\n", This, child, outChild); - return node_append_child(&This->node, child, outChild); -} + TRACE("%p, %d, %p.\n", iface, deep, node); -static HRESULT WINAPI dom_pi_hasChildNodes( - IXMLDOMProcessingInstruction *iface, - VARIANT_BOOL *ret) -{ - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p)\n", This, ret); - return node_has_childnodes(&This->node, ret); + return node_clone(pi->node, deep, node); } -static HRESULT WINAPI dom_pi_get_ownerDocument( - IXMLDOMProcessingInstruction *iface, - IXMLDOMDocument **doc) +static HRESULT WINAPI dom_pi_get_nodeTypeString(IXMLDOMProcessingInstruction *iface, BSTR *p) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p)\n", This, doc); - return node_get_owner_doc(&This->node, doc); -} + TRACE("%p, %p.\n", iface, p); -static HRESULT WINAPI dom_pi_cloneNode( - IXMLDOMProcessingInstruction *iface, - VARIANT_BOOL deep, IXMLDOMNode** outNode) -{ - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%d %p)\n", This, deep, outNode); - return node_clone( &This->node, deep, outNode ); + return return_bstr(L"processinginstruction", p); } -static HRESULT WINAPI dom_pi_get_nodeTypeString( - IXMLDOMProcessingInstruction *iface, - BSTR* p) +static HRESULT WINAPI dom_pi_get_text(IXMLDOMProcessingInstruction *iface, BSTR *p) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return return_bstr(L"processinginstruction", p); + return node_get_text(pi->node, p); } -static HRESULT WINAPI dom_pi_get_text( - IXMLDOMProcessingInstruction *iface, - BSTR* p) +static HRESULT WINAPI dom_pi_put_text(IXMLDOMProcessingInstruction *iface, BSTR p) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_text(&This->node, p); -} + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); -static HRESULT WINAPI dom_pi_put_text( - IXMLDOMProcessingInstruction *iface, - BSTR p) -{ - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - return node_put_text( &This->node, p ); + TRACE("%p, %s.\n", iface, debugstr_w(p)); + + return node_put_data(pi->node, p); } -static HRESULT WINAPI dom_pi_get_specified( - IXMLDOMProcessingInstruction *iface, - VARIANT_BOOL* isSpecified) +static HRESULT WINAPI dom_pi_get_specified(IXMLDOMProcessingInstruction *iface, VARIANT_BOOL *v) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - FIXME("(%p)->(%p) stub!\n", This, isSpecified); - *isSpecified = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI dom_pi_get_definition( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode** definitionNode) +static HRESULT WINAPI dom_pi_get_definition(IXMLDOMProcessingInstruction *iface, IXMLDOMNode **node) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - FIXME("(%p)->(%p)\n", This, definitionNode); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI dom_pi_get_nodeTypedValue( - IXMLDOMProcessingInstruction *iface, - VARIANT* v) +static HRESULT WINAPI dom_pi_get_nodeTypedValue(IXMLDOMProcessingInstruction *iface, VARIANT *v) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p)\n", This, v); - return node_get_content(&This->node, v); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); + + TRACE("%p, %p.\n", iface, v); + + return node_get_value(pi->node, v); } -static HRESULT WINAPI dom_pi_put_nodeTypedValue( - IXMLDOMProcessingInstruction *iface, - VARIANT typedValue) +static HRESULT WINAPI dom_pi_put_nodeTypedValue(IXMLDOMProcessingInstruction *iface, VARIANT v) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); + FIXME("%p, %s.\n", iface, debugstr_variant(&v)); + return E_NOTIMPL; } -static HRESULT WINAPI dom_pi_get_dataType( - IXMLDOMProcessingInstruction *iface, - VARIANT* typename) +static HRESULT WINAPI dom_pi_get_dataType(IXMLDOMProcessingInstruction *iface, VARIANT *v) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p)\n", This, typename); - return return_null_var( typename ); + TRACE("%p, %p.\n", iface, v); + + return return_null_var(v); } -static HRESULT WINAPI dom_pi_put_dataType( - IXMLDOMProcessingInstruction *iface, - BSTR p) +static HRESULT WINAPI dom_pi_put_dataType(IXMLDOMProcessingInstruction *iface, BSTR p) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); + TRACE("%p, %s.\n", iface, debugstr_w(p)); - if(!p) + if (!p) return E_INVALIDARG; return E_FAIL; } -static HRESULT WINAPI dom_pi_get_xml( - IXMLDOMProcessingInstruction *iface, - BSTR* p) +static HRESULT WINAPI dom_pi_get_xml(IXMLDOMProcessingInstruction *iface, BSTR *p) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_xml(&This->node, FALSE, p); + return node_get_xml(pi->node, p); } -static HRESULT WINAPI dom_pi_transformNode( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode *node, BSTR *p) +static HRESULT WINAPI dom_pi_transformNode(IXMLDOMProcessingInstruction *iface, IXMLDOMNode *node, BSTR *p) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p %p)\n", This, node, p); - return node_transform_node(&This->node, node, p); -} + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); -static HRESULT WINAPI dom_pi_selectNodes( - IXMLDOMProcessingInstruction *iface, - BSTR p, IXMLDOMNodeList** outList) -{ - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); - return node_select_nodes(&This->node, p, outList); -} + TRACE("%p, %p, %p.\n", iface, node, p); -static HRESULT WINAPI dom_pi_selectSingleNode( - IXMLDOMProcessingInstruction *iface, - BSTR p, IXMLDOMNode** outNode) -{ - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); - return node_select_singlenode(&This->node, p, outNode); + return node_transform_node(pi->node, node, p); } -static HRESULT WINAPI dom_pi_get_parsed( - IXMLDOMProcessingInstruction *iface, - VARIANT_BOOL* isParsed) +static HRESULT WINAPI dom_pi_selectNodes(IXMLDOMProcessingInstruction *iface, BSTR p, IXMLDOMNodeList **list) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - FIXME("(%p)->(%p) stub!\n", This, isParsed); - *isParsed = VARIANT_TRUE; - return S_OK; -} + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction( iface ); -static HRESULT WINAPI dom_pi_get_namespaceURI( - IXMLDOMProcessingInstruction *iface, - BSTR* p) -{ - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_namespaceURI(&This->node, p); -} + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), list); -static HRESULT WINAPI dom_pi_get_prefix( - IXMLDOMProcessingInstruction *iface, - BSTR* prefix) -{ - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p)\n", This, prefix); - return return_null_bstr( prefix ); + return node_select_nodes(pi->node, p, list); } -static HRESULT WINAPI dom_pi_get_baseName( - IXMLDOMProcessingInstruction *iface, - BSTR* name) +static HRESULT WINAPI dom_pi_selectSingleNode(IXMLDOMProcessingInstruction *iface, BSTR p, IXMLDOMNode **node) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - TRACE("(%p)->(%p)\n", This, name); - return node_get_base_name( &This->node, name ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), node); + + return node_select_singlenode(pi->node, p, node); } -static HRESULT WINAPI dom_pi_transformNodeToObject( - IXMLDOMProcessingInstruction *iface, - IXMLDOMNode* domNode, VARIANT var1) +static HRESULT WINAPI dom_pi_get_parsed(IXMLDOMProcessingInstruction *iface, VARIANT_BOOL *v) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); - return E_NOTIMPL; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; + return S_OK; } -static HRESULT WINAPI dom_pi_get_target( - IXMLDOMProcessingInstruction *iface, - BSTR *p) +static HRESULT WINAPI dom_pi_get_namespaceURI(IXMLDOMProcessingInstruction *iface, BSTR *p) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - /* target returns the same value as nodeName property */ - return node_get_nodeName(&This->node, p); + return node_get_namespaceURI(pi->node, p); } -static HRESULT WINAPI dom_pi_get_data( - IXMLDOMProcessingInstruction *iface, - BSTR *p) +static HRESULT WINAPI dom_pi_get_prefix(IXMLDOMProcessingInstruction *iface, BSTR *prefix) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - HRESULT hr; - VARIANT ret; + TRACE("%p, %p.\n", iface, prefix); - TRACE("(%p)->(%p)\n", This, p); + return return_null_bstr(prefix); +} - if(!p) - return E_INVALIDARG; +static HRESULT WINAPI dom_pi_get_baseName(IXMLDOMProcessingInstruction *iface, BSTR *name) +{ + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - hr = IXMLDOMProcessingInstruction_get_nodeValue( iface, &ret ); - if(hr == S_OK) - { - *p = V_BSTR(&ret); - } + TRACE("%p, %p.\n", iface, name); - return hr; + return node_get_base_name(pi->node, name); } -static HRESULT WINAPI dom_pi_put_data( - IXMLDOMProcessingInstruction *iface, - BSTR data) +static HRESULT WINAPI dom_pi_transformNodeToObject(IXMLDOMProcessingInstruction *iface, IXMLDOMNode *node, VARIANT var1) { - dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface ); - BSTR target; - HRESULT hr; + FIXME("%p, %p, %s.\n", iface, node, debugstr_variant(&var1)); - TRACE("(%p)->(%s)\n", This, debugstr_w(data) ); + return E_NOTIMPL; +} - /* cannot set data to a PI node whose target is 'xml' */ - hr = IXMLDOMProcessingInstruction_get_nodeName(iface, &target); - if(hr == S_OK) - { - if(!wcscmp(target, L"xml")) - { - SysFreeString(target); - return E_FAIL; - } +static HRESULT WINAPI dom_pi_get_target(IXMLDOMProcessingInstruction *iface, BSTR *p) +{ + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - SysFreeString(target); - } + TRACE("%p, %p.\n", iface, p); - return node_set_content(&This->node, data); + return node_get_name(pi->node, p); } -HRESULT dom_pi_put_xml_decl(IXMLDOMNode *node, BSTR data) +static HRESULT WINAPI dom_pi_get_data(IXMLDOMProcessingInstruction *iface, BSTR *p) { - xmlnode *node_obj; - HRESULT hr; - BSTR name; + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction(iface); - if (!data) - return XML_E_XMLDECLSYNTAX; + TRACE("%p, %p.\n", iface, p); - node_obj = get_node_obj(node); - hr = node_set_content(node_obj, data); - if (FAILED(hr)) - return hr; + return node_get_data(pi->node, p); +} - hr = node_get_nodeName(node_obj, &name); - if (FAILED(hr)) - return hr; +static HRESULT WINAPI dom_pi_put_data(IXMLDOMProcessingInstruction *iface, BSTR data) +{ + dom_pi *pi = impl_from_IXMLDOMProcessingInstruction( iface ); - if (!wcscmp(name, L"xml") && !node_obj->node->properties) - hr = parse_xml_decl(node_obj->node); - else - hr = S_OK; + TRACE("%p, %s.\n", iface, debugstr_w(data)); - SysFreeString(name); - return hr; + return node_put_data(pi->node, data); } static const struct IXMLDOMProcessingInstructionVtbl dom_pi_vtbl = @@ -814,139 +542,113 @@ static const struct IXMLDOMProcessingInstructionVtbl dom_pi_vtbl = dom_pi_get_prefix, dom_pi_get_baseName, dom_pi_transformNodeToObject, - dom_pi_get_target, dom_pi_get_data, - dom_pi_put_data + dom_pi_put_data, }; -static xmlAttrPtr node_has_prop(const xmlNode *node, const xmlChar *name) -{ - xmlAttrPtr prop; - - /* xmlHasNsProp accepts only nodes of type XML_ELEMENT_NODE, - * so we have to look for an attribute in the node by hand. - */ - - prop = node->properties; - - while (prop) - { - if (xmlStrEqual(prop->name, name)) - return prop; - - prop = prop->next; - } - - return NULL; -} - -static HRESULT dom_pi_get_qualified_item(const xmlNodePtr node, BSTR name, BSTR uri, +static HRESULT dom_pi_get_qualified_item(const struct domnode *node, BSTR name, BSTR uri, IXMLDOMNode **item) { - FIXME("(%p)->(%s %s %p): stub\n", node, debugstr_w(name), debugstr_w(uri), item); + FIXME("%p, %s, %s, %p: stub\n", node, debugstr_w(name), debugstr_w(uri), item); + return E_NOTIMPL; } -static HRESULT dom_pi_get_named_item(const xmlNodePtr node, BSTR name, IXMLDOMNode **item) +static HRESULT dom_pi_get_named_item(const struct domnode *node, BSTR name, IXMLDOMNode **item) { - xmlChar *nameA; - xmlAttrPtr attr; - - TRACE("(%p)->(%s %p)\n", node, debugstr_w(name), item); + TRACE("%p, %s, %p.\n", node, debugstr_w(name), item); - if (!item) return E_POINTER; + if (!item) + return E_POINTER; - nameA = xmlchar_from_wchar(name); - if (!nameA) return E_OUTOFMEMORY; - - attr = node_has_prop(node, nameA); - free(nameA); - - if (!attr) - { - *item = NULL; - return S_FALSE; - } - - *item = create_node((xmlNodePtr)attr); - - return S_OK; + return node_get_attribute(node, name, (IXMLDOMAttribute **)item); } -static HRESULT dom_pi_set_named_item(xmlNodePtr node, IXMLDOMNode *newItem, IXMLDOMNode **namedItem) +static HRESULT dom_pi_set_named_item(struct domnode *node, IXMLDOMNode *newItem, IXMLDOMNode **namedItem) { - FIXME("(%p)->(%p %p): stub\n", node, newItem, namedItem ); - return E_NOTIMPL; + TRACE("%p, %p, %p.\n", node, newItem, namedItem); + + return node_set_attribute(node, newItem, namedItem); } -static HRESULT dom_pi_remove_qualified_item(xmlNodePtr node, BSTR name, BSTR uri, IXMLDOMNode **item) +static HRESULT dom_pi_remove_qualified_item(struct domnode *node, BSTR name, BSTR uri, IXMLDOMNode **item) { - FIXME("(%p)->(%s %s %p): stub\n", node, debugstr_w(name), debugstr_w(uri), item); + FIXME("%p, %s, %s, %p: stub\n", node, debugstr_w(name), debugstr_w(uri), item); + return E_NOTIMPL; } -static HRESULT dom_pi_remove_named_item(xmlNodePtr node, BSTR name, IXMLDOMNode **item) +static HRESULT dom_pi_remove_named_item(struct domnode *node, BSTR name, IXMLDOMNode **item) { - FIXME("(%p)->(%s %p): stub\n", node, debugstr_w(name), item); - return E_NOTIMPL; + TRACE("%p, %s, %p.\n", node, debugstr_w(name), item); + + return node_remove_attribute(node, name, item); } -static HRESULT dom_pi_get_item(const xmlNodePtr node, LONG index, IXMLDOMNode **item) +static HRESULT dom_pi_get_item(struct domnode *node, LONG index, IXMLDOMNode **item) { - FIXME("%p, %ld, %p: stub\n", node, index, item); - return E_NOTIMPL; + TRACE("%p, %ld, %p.\n", node, index, item); + + return node_get_attribute_by_index(node, index, item); } -static HRESULT dom_pi_get_length(const xmlNodePtr node, LONG *length) +static HRESULT dom_pi_get_length(struct domnode *node, LONG *length) { - FIXME("(%p)->(%p): stub\n", node, length); + TRACE("%p, %p.\n", node, length); - *length = 0; + *length = list_count(&node->attributes); return S_OK; } -static HRESULT dom_pi_next_node(const xmlNodePtr node, LONG *iter, IXMLDOMNode **nextNode) +static HRESULT dom_pi_next_node(const struct domnode *node, LONG *iter, IXMLDOMNode **nextNode) { FIXME("%p, %ld, %p: stub\n", node, *iter, nextNode); return E_NOTIMPL; } -static const struct nodemap_funcs dom_pi_attr_map = { - dom_pi_get_named_item, - dom_pi_set_named_item, - dom_pi_remove_named_item, - dom_pi_get_item, - dom_pi_get_length, - dom_pi_get_qualified_item, - dom_pi_remove_qualified_item, - dom_pi_next_node +static const struct nodemap_funcs dom_pi_attr_map = +{ + .get_named_item = dom_pi_get_named_item, + .set_named_item = dom_pi_set_named_item, + .remove_named_item = dom_pi_remove_named_item, + .get_item = dom_pi_get_item, + .get_length = dom_pi_get_length, + .get_qualified_item = dom_pi_get_qualified_item, + .remove_qualified_item = dom_pi_remove_qualified_item, + .next_node = dom_pi_next_node, }; -static const tid_t dompi_iface_tids[] = { +static const tid_t dompi_iface_tids[] = +{ IXMLDOMProcessingInstruction_tid, 0 }; -static dispex_static_data_t dompi_dispex = { +static dispex_static_data_t dompi_dispex = +{ NULL, IXMLDOMProcessingInstruction_tid, NULL, dompi_iface_tids }; -IUnknown* create_pi( xmlNodePtr pi ) +HRESULT create_pi(struct domnode *node, IUnknown **obj) { - dom_pi *This; + dom_pi *object; + + *obj = NULL; - This = malloc(sizeof(*This)); - if ( !This ) - return NULL; + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; - This->IXMLDOMProcessingInstruction_iface.lpVtbl = &dom_pi_vtbl; - This->ref = 1; + object->IXMLDOMProcessingInstruction_iface.lpVtbl = &dom_pi_vtbl; + object->refcount = 1; + object->node = domnode_addref(node); - init_xmlnode(&This->node, pi, (IXMLDOMNode*)&This->IXMLDOMProcessingInstruction_iface, &dompi_dispex); + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMProcessingInstruction_iface, &dompi_dispex); - return (IUnknown*)&This->IXMLDOMProcessingInstruction_iface; + *obj = (IUnknown *)&object->IXMLDOMProcessingInstruction_iface; + + return S_OK; } diff --git a/dlls/msxml3/saxreader.c b/dlls/msxml3/saxreader.c index 89f82722058..3107d74cca8 100644 --- a/dlls/msxml3/saxreader.c +++ b/dlls/msxml3/saxreader.c @@ -39,6 +39,9 @@ #include "msxml_private.h" +#include "initguid.h" +#include "saxreader_extensions.h" + WINE_DEFAULT_DEBUG_CHANNEL(msxml); struct stream_wrapper @@ -139,7 +142,7 @@ static const ISequentialStreamVtbl stream_wrapper_vtbl = stream_wrapper_Write, }; -static HRESULT stream_wrapper_create(const void *buffer, DWORD size, ISequentialStream **ret) +HRESULT stream_wrapper_create(const void *buffer, DWORD size, ISequentialStream **ret) { struct stream_wrapper *object; @@ -170,6 +173,7 @@ enum error_codes E_SAX_BADSTARTNAMECHAR = 0xc00ce504, E_SAX_BADNAMECHAR = 0xc00ce505, E_SAX_BADCHARINSTRING = 0xc00ce506, + E_SAX_XMLDECLSYNTAX = 0xc00ce507, E_SAX_MISSINGWHITESPACE = 0xc00ce509, E_SAX_EXPECTINGTAGEND = 0xc00ce50a, E_SAX_BADCHARINDTD = 0xc00ce50b, @@ -196,6 +200,7 @@ enum error_codes E_SAX_UNCLOSEDCDATA = 0xc00ce564, E_SAX_BADDECLNAME = 0xc00ce565, E_SAX_RESERVEDNAMESPACE = 0xc00ce568, + E_SAX_UNEXPECTED_ATTRIBUTE = 0xc00ce56c, E_SAX_ENDTAGMISMATCH = 0xc00ce56d, E_SAX_INVALIDENCODING = 0xc00ce56e, E_SAX_INVALIDSWITCH = 0xc00ce56f, @@ -239,16 +244,9 @@ struct attribute bool nsdef; }; -struct name -{ - BSTR prefix; - BSTR local; - BSTR qname; -}; - struct attlist_attr { - struct name name; + struct parsed_name name; BSTR type; BSTR valuetype; BSTR value; @@ -385,6 +383,7 @@ enum saxhandler_type SAXEntityResolver, SAXErrorHandler, SAXLexicalHandler, + SAXExtensionHandler, SAXHandler_Last }; @@ -400,6 +399,12 @@ struct saxcontenthandler_iface IVBSAXContentHandler *vbhandler; }; +struct saxextensionhandler_iface +{ + ISAXExtensionHandler *handler; + IDispatch *vbhandler; +}; + struct saxerrorhandler_iface { ISAXErrorHandler *handler; @@ -440,6 +445,7 @@ struct saxhandler_iface struct saxlexicalhandler_iface lexical; struct saxdtdhandler_iface dtd; struct saxdeclhandler_iface decl; + struct saxextensionhandler_iface extension; struct saxanyhandler_iface anyhandler; } u; }; @@ -449,6 +455,7 @@ struct saxreader DispatchEx dispex; IVBSAXXMLReader IVBSAXXMLReader_iface; ISAXXMLReader ISAXXMLReader_iface; + ISAXXMLReaderExtension ISAXXMLReaderExtension_iface; LONG refcount; struct saxhandler_iface saxhandlers[SAXHandler_Last]; @@ -505,6 +512,11 @@ static struct saxcontenthandler_iface *saxreader_get_contenthandler(struct saxre return &reader->saxhandlers[SAXContentHandler].u.content; } +static struct saxextensionhandler_iface *saxreader_get_extensionhandler(struct saxreader *reader) +{ + return &reader->saxhandlers[SAXExtensionHandler].u.extension; +} + static struct saxerrorhandler_iface *saxreader_get_errorhandler(struct saxreader *reader) { return &reader->saxhandlers[SAXErrorHandler].u.error; @@ -833,6 +845,13 @@ enum saxreader_state SAX_PARSER_EOF, }; +struct string_buffer +{ + WCHAR *data; + size_t count; + size_t capacity; +}; + struct saxlocator { IVBSAXLocator IVBSAXLocator_iface; @@ -868,6 +887,8 @@ struct saxlocator struct list entities; } dtd; + bool collect; + struct string_buffer scratch; struct input_buffer buffer; struct text_position start_document_position; HRESULT status; @@ -883,6 +904,11 @@ static inline struct saxreader *impl_from_ISAXXMLReader(ISAXXMLReader *iface) return CONTAINING_RECORD(iface, struct saxreader, ISAXXMLReader_iface); } +static inline struct saxreader *impl_from_ISAXXMLReaderExtension(ISAXXMLReaderExtension *iface) +{ + return CONTAINING_RECORD(iface, struct saxreader, ISAXXMLReaderExtension_iface); +} + static inline struct saxlocator *impl_from_IVBSAXLocator(IVBSAXLocator *iface) { return CONTAINING_RECORD(iface, struct saxlocator, IVBSAXLocator_iface); @@ -941,6 +967,9 @@ static BSTR saxreader_alloc_string(struct saxlocator *locator, const WCHAR *str) { BSTR ret; + if (!str) + return NULL; + if (!(ret = SysAllocString(str))) saxreader_set_error(locator, E_OUTOFMEMORY); @@ -1896,9 +1925,17 @@ static bool saxreader_reserve_buffer(struct saxlocator *locator, struct encoded_ buffer->written + size, sizeof(*buffer->data)); } +static BSTR saxreader_string_to_bstr(struct saxlocator *locator, struct string_buffer *buffer) +{ + BSTR str = saxreader_alloc_stringlen(locator, buffer->data, buffer->count); + free(buffer->data); + memset(buffer, 0, sizeof(*buffer)); + return str; +} + static bool saxreader_limit_xml_size(struct saxlocator *locator, ULONG read) { - if (locator->saxreader->max_xml_size > 0) + if (locator->saxreader && locator->saxreader->max_xml_size > 0) { locator->buffer.raw_size += read; if (locator->buffer.raw_size > locator->saxreader->max_xml_size * 1024) @@ -2087,6 +2124,19 @@ static bool saxreader_pop_entity(struct saxlocator *locator) return list_empty(&input->entities); } +static void saxreader_string_append(struct saxlocator *locator, struct string_buffer *buffer, + const WCHAR *str, UINT len) +{ + if (!saxreader_array_reserve(locator, (void **)&buffer->data, &buffer->capacity, buffer->count + len, sizeof(*str))) + { + saxreader_set_error(locator, E_OUTOFMEMORY); + return; + } + + memcpy(buffer->data + buffer->count, str, len * sizeof(WCHAR)); + buffer->count += len; +} + static void saxreader_skip(struct saxlocator *locator, int n) { struct encoded_buffer *buffer = &locator->buffer.utf16; @@ -2095,6 +2145,9 @@ static void saxreader_skip(struct saxlocator *locator, int n) while (locator->status == S_OK && (ch = *saxreader_get_ptr(locator)) && n--) { + if (locator->collect) + saxreader_string_append(locator, &locator->scratch, &ch, 1); + if (saxreader_pop_entity(locator)) saxreader_update_position(locator, ch); @@ -2177,7 +2230,7 @@ struct ns struct element { struct list entry; - struct name name; + struct parsed_name name; BSTR uri; struct @@ -2218,6 +2271,29 @@ static void saxlocator_put_document_locator(struct saxlocator *locator) locator->status = hr; } +static void saxlocator_xmldecl(struct saxlocator *locator) +{ + struct saxextensionhandler_iface *handler = saxreader_get_extensionhandler(locator->saxreader); + HRESULT hr = S_OK; + + if (locator->status != S_OK) + return; + + if (!locator->saxreader->xmldecl_version) + return; + + if (saxreader_has_handler(locator, SAXExtensionHandler)) + { + if (!locator->vbInterface) + hr = ISAXExtensionHandler_xmldecl(handler->handler, + locator->saxreader->xmldecl_version, + locator->saxreader->xmldecl_encoding, + locator->saxreader->xmldecl_standalone); + } + + locator->status = saxlocator_callback_result(locator, hr); +} + static void saxlocator_start_document(struct saxlocator *locator) { struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(locator->saxreader); @@ -2745,6 +2821,28 @@ static void saxlocator_enddtd(struct saxlocator *locator) locator->status = saxlocator_callback_result(locator, hr); } +static void saxlocator_extension_dtd(struct saxlocator *locator) +{ + struct saxextensionhandler_iface *handler = saxreader_get_extensionhandler(locator->saxreader); + HRESULT hr = S_OK; + BSTR str; + + if (locator->status != S_OK) + return; + + str = saxreader_string_to_bstr(locator, &locator->scratch); + if (saxreader_has_handler(locator, SAXExtensionHandler)) + { + if (!locator->vbInterface) + hr = ISAXExtensionHandler_dtd(handler->handler, str); + } + SysFreeString(str); + + locator->collect = false; + + locator->status = saxlocator_callback_result(locator, hr); +} + static void saxlocator_start_entity(struct saxlocator *locator, const struct text_position *position, BSTR name) { struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(locator->saxreader); @@ -2789,26 +2887,6 @@ static void saxlocator_end_entity(struct saxlocator *locator, const struct text_ locator->status = saxlocator_callback_result(locator, hr); } -struct string_buffer -{ - WCHAR *data; - size_t count; - size_t capacity; -}; - -static void saxreader_string_append(struct saxlocator *locator, struct string_buffer *buffer, - const WCHAR *str, UINT len) -{ - if (!saxreader_array_reserve(locator, (void **)&buffer->data, &buffer->capacity, buffer->count + len, sizeof(*str))) - { - saxreader_set_error(locator, E_OUTOFMEMORY); - return; - } - - memcpy(buffer->data + buffer->count, str, len * sizeof(WCHAR)); - buffer->count += len; -} - static void saxreader_string_append_bstr(struct saxlocator *locator, struct string_buffer *buffer, BSTR *str) { saxreader_string_append(locator, buffer, *str, SysStringLen(*str)); @@ -2816,18 +2894,10 @@ static void saxreader_string_append_bstr(struct saxlocator *locator, struct stri *str = NULL; } -static BSTR saxreader_string_to_bstr(struct saxlocator *locator, struct string_buffer *buffer) -{ - BSTR str = saxreader_alloc_stringlen(locator, buffer->data, buffer->count); - free(buffer->data); - memset(buffer, 0, sizeof(*buffer)); - return str; -} - /* [3] S ::= (#x20 | #x9 | #xD | #xA)+ */ static bool saxreader_is_space(WCHAR ch) { - return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; + return xml_is_space(ch); } /* [3] S ::= (#x20 | #x9 | #xD | #xA)+ */ @@ -2860,29 +2930,6 @@ static bool saxreader_skip_required_spaces(struct saxlocator *locator) return ret; } -/* [25] Eq ::= S? '=' S? */ -static void saxreader_parse_eq(struct saxlocator *locator) -{ - saxreader_skipspaces(locator); - if (!saxreader_cmp(locator, L"=")) - return saxreader_set_error(locator, E_SAX_MISSINGEQUALS); - saxreader_skipspaces(locator); -} - -/* [26] VersionNum ::= '1.' [0-9]+ */ -static void saxreader_parse_versionnum(struct saxlocator *locator) -{ - if (saxreader_cmp(locator, L"1.0")) - { - SysFreeString(locator->saxreader->xmldecl_version); - locator->saxreader->xmldecl_version = saxreader_alloc_string(locator, L"1.0"); - } - else - { - saxreader_set_error(locator, E_SAX_INVALID_VERSION); - } -} - static WCHAR saxreader_is_quote(struct saxlocator *locator) { const WCHAR *ptr; @@ -2896,22 +2943,17 @@ static WCHAR saxreader_is_quote(struct saxlocator *locator) } /* [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"') */ -static void saxreader_parse_versioninfo(struct saxlocator *locator) +/* [26] VersionNum ::= '1.' [0-9]+ */ +static void saxreader_parse_versioninfo(struct saxlocator *locator, const struct parsed_name *name, BSTR value) { - WCHAR q[2] = { 0 }; - - if (!saxreader_cmp(locator, L"version")) - return saxreader_set_error(locator, E_SAX_BAD_XMLDECL); - - saxreader_parse_eq(locator); - if (!(q[0] = saxreader_is_quote(locator))) - saxreader_set_error(locator, E_SAX_MISSINGQUOTE); - saxreader_skip(locator, 1); + if (wcscmp(name->qname, L"version")) + return saxreader_set_error(locator, E_SAX_UNEXPECTED_ATTRIBUTE); - saxreader_parse_versionnum(locator); + if (wcscmp(value, L"1.0")) + return saxreader_set_error(locator, E_SAX_INVALID_VERSION); - if (!saxreader_cmp(locator, q)) - saxreader_set_error(locator, E_SAX_MISSINGQUOTE); + SysFreeString(locator->saxreader->xmldecl_version); + locator->saxreader->xmldecl_version = saxreader_alloc_string(locator, L"1.0"); } static void saxreader_switch_encoding(struct saxlocator *locator, UINT codepage) @@ -2927,34 +2969,14 @@ static void saxreader_switch_encoding(struct saxlocator *locator, UINT codepage) } /* [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" ) */ -static void saxreader_parse_encdecl(struct saxlocator *locator) +static void saxreader_parse_encdecl(struct saxlocator *locator, const struct parsed_name *name, BSTR value) { - struct string_buffer buffer = { 0 }; - WCHAR q[2] = { 0 }, ch; UINT codepage; - saxreader_skip_required_spaces(locator); - if (!saxreader_cmp(locator, L"encoding")) - return; - - saxreader_parse_eq(locator); + if (wcscmp(name->qname, L"encoding")) + return saxreader_set_error(locator, E_SAX_UNEXPECTED_ATTRIBUTE); - if (!(q[0] = saxreader_is_quote(locator))) - saxreader_set_error(locator, E_SAX_MISSINGQUOTE); - saxreader_skip(locator, 1); - - ch = *saxreader_get_ptr(locator); - while (ch != *q) - { - saxreader_string_append(locator, &buffer, &ch, 1); - saxreader_skip(locator, 1); - ch = *saxreader_get_ptr(locator); - } - - if (!saxreader_cmp(locator, q)) - saxreader_set_error(locator, E_SAX_MISSINGQUOTE); - - locator->saxreader->xmldecl_encoding = saxreader_string_to_bstr(locator, &buffer); + locator->saxreader->xmldecl_encoding = saxreader_alloc_string(locator, value); TRACE("encoding name %s\n", debugstr_w(locator->saxreader->xmldecl_encoding)); /* Switch encoding only in UTF-8 -> mbtowc-able direction. */ @@ -2964,39 +2986,27 @@ static void saxreader_parse_encdecl(struct saxlocator *locator) if (saxreader_get_encoding_codepage(locator->saxreader->xmldecl_encoding, &codepage)) saxreader_switch_encoding(locator, codepage); else if (!saxreader_can_ignore_encoding(locator->saxreader->xmldecl_encoding)) + { FIXME("Unsupported encoding %s.\n", debugstr_w(locator->saxreader->xmldecl_encoding)); + saxreader_set_error(locator, E_SAX_INVALIDENCODING); + } } } /* [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"')) */ -static void saxreader_parse_sddecl(struct saxlocator *locator) +static void saxreader_parse_sddecl(struct saxlocator *locator, const struct parsed_name *name, BSTR value) { - WCHAR q[2] = { 0 }; - - saxreader_skipspaces(locator); - - if (!saxreader_cmp(locator, L"standalone")) - return; - - saxreader_parse_eq(locator); - - if (!(q[0] = saxreader_is_quote(locator))) - saxreader_set_error(locator, E_SAX_MISSINGQUOTE); - saxreader_skip(locator, 1); + if (wcscmp(name->qname, L"standalone")) + return saxreader_set_error(locator, E_SAX_UNEXPECTED_ATTRIBUTE); - if (saxreader_cmp(locator, L"yes")) - locator->saxreader->xmldecl_standalone = saxreader_alloc_string(locator, L"yes"); - else if (saxreader_cmp(locator, L"no")) - locator->saxreader->xmldecl_standalone = saxreader_alloc_string(locator, L"no"); + if (!wcscmp(value, L"yes") || !wcscmp(value, L"no")) + locator->saxreader->xmldecl_standalone = saxreader_alloc_string(locator, value); else saxreader_set_error(locator, E_SAX_INVALID_STANDALONE); - - if (!saxreader_cmp(locator, q)) - saxreader_set_error(locator, E_SAX_MISSINGQUOTE); } -/* [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' */ -static void saxreader_parse_xmldecl(struct saxlocator *locator) +/* +static bool saxreader_parse_xmldecl(struct saxlocator *locator) { WCHAR ch; @@ -3004,21 +3014,21 @@ static void saxreader_parse_xmldecl(struct saxlocator *locator) ch = saxreader_get_char(locator, 5); if (!saxreader_peek(locator, L"<?xml", 5) || !saxreader_is_space(ch)) - return; + return false; saxreader_skip(locator, 5); saxreader_skipspaces(locator); saxreader_parse_versioninfo(locator); if (saxreader_cmp(locator, L"?>")) - return; + return true; saxreader_parse_encdecl(locator); if (locator->saxreader->xmldecl_encoding) { if (saxreader_cmp(locator, L"?>")) - return; + return true; saxreader_skip_required_spaces(locator); } @@ -3028,7 +3038,11 @@ static void saxreader_parse_xmldecl(struct saxlocator *locator) if (!saxreader_cmp(locator, L"?>")) saxreader_set_error(locator, E_SAX_BAD_XMLDECL); + + return true; } +*/ +static BSTR saxreader_parse_xmldecl_attribute(struct saxlocator *locator, struct parsed_name *name); /* [85] BaseChar ::= ... */ static bool saxreader_is_basechar(WCHAR ch) @@ -3352,7 +3366,7 @@ static BSTR saxreader_parse_ncname(struct saxlocator *locator) [8 NS] PrefixedName ::= Prefix ':' LocalPart [9 NS] UnprefixedName ::= LocalPart [10 NS] Prefix ::= NCName */ -static void saxreader_parse_qname(struct saxlocator *locator, struct name *name) +static void saxreader_parse_qname(struct saxlocator *locator, struct parsed_name *name) { struct string_buffer buffer = { 0 }; BSTR ncname; @@ -3382,7 +3396,37 @@ static void saxreader_parse_qname(struct saxlocator *locator, struct name *name) name->qname = saxreader_string_to_bstr(locator, &buffer); } -static struct element *saxreader_new_element(struct saxlocator *locator, struct name *name) +static const WCHAR * validate_ncname(const WCHAR *name) +{ + const WCHAR *p = name; + + if (!saxreader_is_ncname_startchar(*p++)) + return NULL; + + while (*p && *p != ':') + { + if (!saxreader_is_ncnamechar(*p)) return NULL; + ++p; + } + + return p; +} + +bool parser_is_valid_qualified_name(const WCHAR *name) +{ + const WCHAR *p; + + p = validate_ncname(name); + if (!p) + return false; + + if (*p == ':') + p = validate_ncname(++p); + + return p && !*p; +} + +static struct element *saxreader_new_element(struct saxlocator *locator, struct parsed_name *name) { struct element *element; @@ -3396,7 +3440,7 @@ static struct element *saxreader_new_element(struct saxlocator *locator, struct return element; } -static void saxreader_free_name(struct name *name) +static void saxreader_free_name(struct parsed_name *name) { SysFreeString(name->prefix); SysFreeString(name->local); @@ -3467,7 +3511,7 @@ static bool saxreader_has_attribute(struct saxlocator *locator, BSTR name) return false; } -static void saxreader_add_attribute(struct saxlocator *locator, const struct name *name, BSTR value, bool nsdef) +static void saxreader_add_attribute(struct saxlocator *locator, const struct parsed_name *name, BSTR value, bool nsdef) { struct attribute *attr; @@ -3743,6 +3787,11 @@ static BSTR saxreader_parse_attvalue(struct saxlocator *locator) else { ch = *saxreader_get_ptr_noread(locator); + if (!ch) + { + saxreader_set_error(locator, E_SAX_BADCHARINSTRING); + break; + } saxreader_string_append(locator, &buffer, &ch, 1); saxreader_skip(locator, 1); } @@ -3755,7 +3804,7 @@ static BSTR saxreader_parse_attvalue(struct saxlocator *locator) } static bool saxreader_add_namespace_attribute(struct saxlocator *locator, struct element *element, - struct name *name, BSTR value) + struct parsed_name *name, BSTR value) { if (name->prefix && !wcscmp(name->prefix, L"xmlns")) saxreader_add_namespace(locator, element, name->local, value); @@ -3770,7 +3819,7 @@ static bool saxreader_add_namespace_attribute(struct saxlocator *locator, struct /* [15 NS] Attribute ::= NSAttName Eq AttValue | QName Eq AttValue */ static void saxreader_parse_attribute(struct saxlocator *locator, struct element *element) { - struct name name; + struct parsed_name name; BSTR value; bool ns; @@ -3782,12 +3831,83 @@ static void saxreader_parse_attribute(struct saxlocator *locator, struct element value = saxreader_parse_attvalue(locator); ns = saxreader_add_namespace_attribute(locator, element, &name, value); - saxreader_add_attribute(locator, &name, value, !!ns); + saxreader_add_attribute(locator, &name, value, ns); saxreader_free_name(&name); SysFreeString(value); } +static BSTR saxreader_parse_xmldecl_attribute(struct saxlocator *locator, struct parsed_name *name) +{ + BSTR value; + + saxreader_parse_qname(locator, name); + saxreader_skipspaces(locator); + if (!saxreader_cmp(locator, L"=")) + saxreader_set_error(locator, E_SAX_MISSINGEQUALS); + saxreader_skipspaces(locator); + value = saxreader_parse_attvalue(locator); + + return value; +} + +/* [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' */ +static void saxreader_parse_xmldecl(struct saxlocator *locator) +{ + struct parsed_name name; + bool done = false; + BSTR value; + WCHAR ch; + + saxreader_more(locator); + + ch = saxreader_get_char(locator, 5); + if (!saxreader_peek(locator, L"<?xml", 5) || !saxreader_is_space(ch)) + return; + saxreader_skip(locator, 5); + saxreader_skipspaces(locator); + + value = saxreader_parse_xmldecl_attribute(locator, &name); + saxreader_parse_versioninfo(locator, &name, value); + saxreader_free_name(&name); + SysFreeString(value); + + saxreader_skipspaces(locator); + if (saxreader_cmp(locator, L"?>")) + return; + + while (!done && locator->status == S_OK) + { + value = saxreader_parse_xmldecl_attribute(locator, &name); + + if (!wcscmp(name.qname, L"encoding")) + { + saxreader_parse_encdecl(locator, &name, value); + } + else if (!wcscmp(name.qname, L"standalone")) + { + saxreader_parse_sddecl(locator, &name, value); + done = true; + } + else + { + saxreader_set_error(locator, E_SAX_UNEXPECTED_ATTRIBUTE); + continue; + } + + saxreader_free_name(&name); + SysFreeString(value); + + saxreader_skipspaces(locator); + if (saxreader_cmp(locator, L"?>")) + return; + } + + saxreader_skipspaces(locator); + if (!saxreader_cmp(locator, L"?>")) + saxreader_set_error(locator, E_SAX_BAD_XMLDECL); +} + static void saxreader_reorder_attributes(struct saxlocator *locator) { size_t count, i, idx; @@ -3823,7 +3943,7 @@ static void saxreader_parse_starttag(struct saxlocator *locator) struct text_position position = { 0 }; bool empty_element = false; struct element *element; - struct name name; + struct parsed_name name; if (!saxreader_cmp(locator, L"<")) return saxreader_set_error(locator, E_SAX_INVALIDATROOTLEVEL); @@ -3864,6 +3984,7 @@ static void saxreader_parse_starttag(struct saxlocator *locator) /* Append default attributes from DTD. */ saxreader_add_default_attributes(locator, element); + saxreader_reorder_attributes(locator); /* The 'uri' string pointers are reused from the namespace stacks. @@ -3885,8 +4006,8 @@ static void saxreader_parse_endtag(struct saxlocator *locator) { struct text_position position; struct element *element; + struct parsed_name name; HRESULT hr = S_OK; - struct name name; /* Skip '</' */ saxreader_skip(locator, 2); @@ -5180,6 +5301,9 @@ static void saxreader_parse_doctype(struct saxlocator *locator) if (locator->saxreader->features & ProhibitDTD) return saxreader_set_error(locator, E_SAX_INVALIDATROOTLEVEL); + if (saxreader_has_handler(locator, SAXExtensionHandler)) + locator->collect = true; + /* Skip <!DOCTYPE */ saxreader_skip(locator, 9); saxreader_skip_required_spaces(locator); @@ -5207,6 +5331,7 @@ static void saxreader_parse_doctype(struct saxlocator *locator) if (sysid) FIXME("External subset is not supported.\n"); + saxlocator_extension_dtd(locator); saxlocator_enddtd(locator); SysFreeString(sysid); @@ -5258,7 +5383,7 @@ static enum xmlencoding saxreader_match_encoding(const char *data, size_t size, return XML_ENCODING_UNKNOWN; } -static void saxreader_detect_encoding(struct saxlocator *locator) +static void saxreader_detect_encoding(struct saxlocator *locator, bool force_utf16) { struct encoded_buffer *utf16 = &locator->buffer.utf16; struct encoded_buffer *raw = &locator->buffer.raw; @@ -5284,7 +5409,7 @@ static void saxreader_detect_encoding(struct saxlocator *locator) raw->written = read; - encoding = saxreader_match_encoding(raw->data, read, &bom); + encoding = force_utf16 ? XML_ENCODING_UTF16LE : saxreader_match_encoding(raw->data, read, &bom); if (encoding == XML_ENCODING_UNKNOWN) { @@ -5302,11 +5427,12 @@ static void saxreader_detect_encoding(struct saxlocator *locator) if (encoding == XML_ENCODING_UTF16LE) { - if (!saxreader_reserve_buffer(locator, utf16, size)) + if (!saxreader_reserve_buffer(locator, utf16, size + sizeof(WCHAR))) return; memcpy(utf16->data + utf16->written, raw->data + bom, size); utf16->written += size; + *(WCHAR *)&utf16->data[utf16->written] = 0; encoded_buffer_cleanup(raw); } @@ -5317,7 +5443,8 @@ static void saxreader_detect_encoding(struct saxlocator *locator) } } -static HRESULT saxreader_parse_stream(struct saxreader *reader, ISequentialStream *stream, bool vbInterface) +static HRESULT saxreader_parse_stream(struct saxreader *reader, ISequentialStream *stream, + bool force_utf16, bool vbInterface) { struct saxlocator *locator; HRESULT hr; @@ -5336,13 +5463,14 @@ static HRESULT saxreader_parse_stream(struct saxreader *reader, ISequentialStrea switch (locator->state) { case SAX_PARSER_START: - saxreader_detect_encoding(locator); + saxreader_detect_encoding(locator, force_utf16); locator->state = SAX_PARSER_XML_DECL; break; case SAX_PARSER_XML_DECL: saxreader_parse_xmldecl(locator); locator->buffer.switched_encoding = true; saxlocator_put_document_locator(locator); + saxlocator_xmldecl(locator); saxlocator_start_document(locator); locator->state = SAX_PARSER_MISC; break; @@ -5465,7 +5593,7 @@ static HRESULT saxreader_parse(struct saxreader *reader, VARIANT input, bool vbI if (FAILED(hr = stream_wrapper_create((const void *)str, SysStringByteLen(str), &stream))) return hr; - hr = saxreader_parse_stream(reader, stream, vbInterface); + hr = saxreader_parse_stream(reader, stream, true, vbInterface); ISequentialStream_Release(stream); break; } @@ -5482,7 +5610,7 @@ static HRESULT saxreader_parse(struct saxreader *reader, VARIANT input, bool vbI size = (uBound - lBound + 1) * SafeArrayGetElemsize(V_ARRAY(&input)); if (SUCCEEDED(hr = stream_wrapper_create(data, size, &stream))) { - hr = saxreader_parse_stream(reader, stream, vbInterface); + hr = saxreader_parse_stream(reader, stream, false, vbInterface); ISequentialStream_Release(stream); } SafeArrayUnaccessData(V_ARRAY(&input)); @@ -5503,7 +5631,7 @@ static HRESULT saxreader_parse(struct saxreader *reader, VARIANT input, bool vbI IXMLDOMDocument_get_xml(xmlDoc, &bstrData); stream_wrapper_create(bstrData, SysStringByteLen(bstrData), &stream); - hr = saxreader_parse_stream(reader, stream, vbInterface); + hr = saxreader_parse_stream(reader, stream, false, vbInterface); ISequentialStream_Release(stream); IXMLDOMDocument_Release(xmlDoc); SysFreeString(bstrData); @@ -5518,7 +5646,7 @@ static HRESULT saxreader_parse(struct saxreader *reader, VARIANT input, bool vbI if (stream) { - hr = saxreader_parse_stream(reader, stream, vbInterface); + hr = saxreader_parse_stream(reader, stream, false, vbInterface); ISequentialStream_Release(stream); } else @@ -5545,7 +5673,7 @@ static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len) if (SUCCEEDED(hr = stream_wrapper_create(ptr, len, &stream))) { - hr = saxreader_parse_stream(reader, stream, true); + hr = saxreader_parse_stream(reader, stream, false, true); ISequentialStream_Release(stream); } return hr; @@ -5559,7 +5687,7 @@ static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len) if (SUCCEEDED(hr = stream_wrapper_create(ptr, len, &stream))) { - hr = saxreader_parse_stream(reader, stream, false); + hr = saxreader_parse_stream(reader, stream, false, false); ISequentialStream_Release(stream); } return hr; @@ -5606,6 +5734,10 @@ static HRESULT saxreader_put_handler_from_variant(struct saxreader *reader, enum case SAXLexicalHandler: riid = vb ? &IID_IVBSAXLexicalHandler : &IID_ISAXLexicalHandler; break; + case SAXExtensionHandler: + riid = &IID_ISAXExtensionHandler; + if (vb) return E_UNEXPECTED; + break; default: ERR("wrong handler type %d\n", type); return E_FAIL; @@ -5664,6 +5796,9 @@ static HRESULT saxreader_put_property(struct saxreader *reader, const WCHAR *pro if (!wcscmp(prop, L"http://xml.org/sax/properties/lexical-handler")) return saxreader_put_handler_from_variant(reader, SAXLexicalHandler, v, vbInterface); + if (!wcscmp(prop, L"http://winehq.org/sax/properties/extension-handler")) + return saxreader_put_handler_from_variant(reader, SAXExtensionHandler, v, vbInterface); + if (!wcscmp(prop, L"max-xml-size")) { int size; @@ -5740,6 +5875,18 @@ static HRESULT saxreader_get_property(const struct saxreader *reader, const WCHA return return_bstr(reader->xmldecl_version, &V_BSTR(value)); } + if (!wcscmp(prop, L"xmldecl-encoding")) + { + V_VT(value) = VT_BSTR; + return return_bstr(reader->xmldecl_encoding, &V_BSTR(value)); + } + + if (!wcscmp(prop, L"xmldecl-standalone")) + { + V_VT(value) = VT_BSTR; + return return_bstr(reader->xmldecl_encoding, &V_BSTR(value)); + } + if (!wcscmp(prop, L"max-xml-size")) { V_VT(value) = VT_I4; @@ -5770,6 +5917,10 @@ static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader *iface, REFIID { *obj = &reader->ISAXXMLReader_iface; } + else if (IsEqualGUID(riid, &IID_ISAXXMLReaderExtension)) + { + *obj = &reader->ISAXXMLReaderExtension_iface; + } else if (dispex_query_interface(&reader->dispex, riid, obj)) { return *obj ? S_OK : E_NOINTERFACE; @@ -6205,6 +6356,38 @@ static const struct ISAXXMLReaderVtbl saxxmlreadervtbl = isaxxmlreader_parseURL }; +static HRESULT WINAPI saxxmlreader_extension_QueryInterface(ISAXXMLReaderExtension *iface, REFIID riid, void **obj) +{ + struct saxreader *reader = impl_from_ISAXXMLReaderExtension(iface); + return IVBSAXXMLReader_QueryInterface(&reader->IVBSAXXMLReader_iface, riid, obj); +} + +static ULONG WINAPI saxxmlreader_extension_AddRef(ISAXXMLReaderExtension *iface) +{ + struct saxreader *reader = impl_from_ISAXXMLReaderExtension(iface); + return IVBSAXXMLReader_AddRef(&reader->IVBSAXXMLReader_iface); +} + +static ULONG WINAPI saxxmlreader_extension_Release(ISAXXMLReaderExtension *iface) +{ + struct saxreader *reader = impl_from_ISAXXMLReaderExtension(iface); + return IVBSAXXMLReader_Release(&reader->IVBSAXXMLReader_iface); +} + +static HRESULT WINAPI saxxmlreader_extension_parseUTF16(ISAXXMLReaderExtension *iface, ISequentialStream *stream) +{ + struct saxreader *reader = impl_from_ISAXXMLReaderExtension(iface); + return saxreader_parse_stream(reader, stream, true, false); +} + +static const struct ISAXXMLReaderExtensionVtbl saxxmlreaderextensionvtbl = +{ + saxxmlreader_extension_QueryInterface, + saxxmlreader_extension_AddRef, + saxxmlreader_extension_Release, + saxxmlreader_extension_parseUTF16, +}; + static const tid_t saxreader_iface_tids[] = { IVBSAXXMLReader_tid, @@ -6219,27 +6402,168 @@ static dispex_static_data_t saxreader_dispex = saxreader_iface_tids }; +static HRESULT saxreader_create(MSXML_VERSION version, struct saxreader **reader) +{ + struct saxreader *object; + + *reader = NULL; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IVBSAXXMLReader_iface.lpVtbl = &vbsaxxmlreadervtbl; + object->ISAXXMLReader_iface.lpVtbl = &saxxmlreadervtbl; + object->ISAXXMLReaderExtension_iface.lpVtbl = &saxxmlreaderextensionvtbl; + object->refcount = 1; + object->features = Namespaces | NamespacePrefixes | NormalizeLineBreaks; + object->version = version; + object->empty_bstr = SysAllocString(L""); + + init_dispex(&object->dispex, (IUnknown *)&object->IVBSAXXMLReader_iface, &saxreader_dispex); + + *reader = object; + + return S_OK; +} + HRESULT SAXXMLReader_create(MSXML_VERSION version, void **obj) { struct saxreader *reader; + HRESULT hr; TRACE("%p\n", obj); - if (!(reader = calloc(1, sizeof(*reader)))) - return E_OUTOFMEMORY; + *obj = NULL; - reader->IVBSAXXMLReader_iface.lpVtbl = &vbsaxxmlreadervtbl; - reader->ISAXXMLReader_iface.lpVtbl = &saxxmlreadervtbl; - reader->refcount = 1; - reader->features = Namespaces | NamespacePrefixes | NormalizeLineBreaks; - reader->version = version; - reader->empty_bstr = SysAllocString(L""); + if (SUCCEEDED(hr = saxreader_create(version, &reader))) + *obj = &reader->IVBSAXXMLReader_iface; - init_dispex(&reader->dispex, (IUnknown *)&reader->IVBSAXXMLReader_iface, &saxreader_dispex); + TRACE("returning iface %p\n", *obj); - *obj = &reader->IVBSAXXMLReader_iface; + return hr; +} - TRACE("returning iface %p\n", *obj); +/* Fixed size buffer variant, to be used without markup. */ +static void saxreader_parse_xmldecl_body(struct saxlocator *locator) +{ + struct parsed_name name; + bool done = false; + BSTR value; - return S_OK; + saxreader_skipspaces(locator); + + value = saxreader_parse_xmldecl_attribute(locator, &name); + saxreader_parse_versioninfo(locator, &name, value); + saxreader_free_name(&name); + SysFreeString(value); + + saxreader_skipspaces(locator); + if (locator->eos) + return; + + while (!done && locator->status == S_OK) + { + value = saxreader_parse_xmldecl_attribute(locator, &name); + + if (!wcscmp(name.qname, L"encoding")) + { + saxreader_parse_encdecl(locator, &name, value); + } + else if (!wcscmp(name.qname, L"standalone")) + { + saxreader_parse_sddecl(locator, &name, value); + done = true; + } + else + { + saxreader_set_error(locator, E_SAX_UNEXPECTED_ATTRIBUTE); + continue; + } + + saxreader_free_name(&name); + SysFreeString(value); + + saxreader_skipspaces(locator); + if (locator->eos) + return; + } + + saxreader_skipspaces(locator); + if (!locator->eos) + saxreader_set_error(locator, E_SAX_BAD_XMLDECL); +} + +HRESULT parse_xml_decl_body(const WCHAR *text, BSTR *version, BSTR *encoding, BSTR *standalone) +{ + struct saxlocator *locator; + ISequentialStream *stream; + struct saxreader *reader; + HRESULT hr; + + *version = *encoding = *standalone = NULL; + + if (!text) + return E_SAX_XMLDECLSYNTAX; + + if (FAILED(hr = stream_wrapper_create(text, wcslen(text) * sizeof(WCHAR), &stream))) + return hr; + + hr = saxreader_create(MSXML3, &reader); + if (SUCCEEDED(hr)) + { + hr = saxlocator_create(reader, stream, false, &locator); + ISAXXMLReader_Release(&reader->ISAXXMLReader_iface); + } + + if (SUCCEEDED(hr)) + { + saxreader_detect_encoding(locator, true); + + saxreader_parse_xmldecl_body(locator); + + *version = saxreader_alloc_string(locator, locator->saxreader->xmldecl_version); + *encoding = saxreader_alloc_string(locator, locator->saxreader->xmldecl_encoding); + *standalone = saxreader_alloc_string(locator, locator->saxreader->xmldecl_standalone); + + hr = locator->status; + + ISAXLocator_Release(&locator->ISAXLocator_iface); + } + + ISequentialStream_Release(stream); + + return hr; +} + +static void saxlocator_standalone_init(struct saxlocator *locator, ISequentialStream *stream) +{ + locator->stream = stream; + locator->buffer.encoding = XML_ENCODING_UTF16LE; + locator->buffer.code_page = convert_get_codepage(XML_ENCODING_UTF16LE); + locator->buffer.chunk_size = 4096; + list_init(&locator->buffer.entities); + saxreader_more(locator); +} + +HRESULT parse_qualified_name(const WCHAR *src, struct parsed_name *name) +{ + struct saxlocator locator = { 0 }; + ISequentialStream *stream; + HRESULT hr; + + if (FAILED(hr = stream_wrapper_create(src, wcslen(src) * sizeof(WCHAR), &stream))) + return hr; + saxlocator_standalone_init(&locator, stream); + + saxreader_parse_qname(&locator, name); + + encoded_buffer_cleanup(&locator.buffer.utf16); + ISequentialStream_Release(stream); + + return locator.status; +} + +void parsed_name_cleanup(struct parsed_name *name) +{ + saxreader_free_name(name); } diff --git a/dlls/msxml3/saxreader_extensions.idl b/dlls/msxml3/saxreader_extensions.idl new file mode 100644 index 00000000000..19fc2476c6b --- /dev/null +++ b/dlls/msxml3/saxreader_extensions.idl @@ -0,0 +1,44 @@ +/* + * Copyright 2026 Nikolay Sivov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma makedep header + +import "unknwn.idl"; +import "objidl.idl"; +import "oaidl.idl"; + +[ + object, + local, + uuid(437d6b59-62b8-4adb-a9bb-20d5fdc43516) +] +interface ISAXExtensionHandler : IUnknown +{ + HRESULT xmldecl([in] BSTR version, [in] BSTR encoding,[in] BSTR standalone); + HRESULT dtd([in] BSTR data); +} + +[ + object, + local, + uuid(b16ef36b-72ed-4caa-9e2d-91453600d030) +] +interface ISAXXMLReaderExtension : IUnknown +{ + HRESULT parseUTF16([in] ISequentialStream *stream); +} diff --git a/dlls/msxml3/schema.c b/dlls/msxml3/schema.c index 2965d5e69b7..bceb8d097a9 100644 --- a/dlls/msxml3/schema.c +++ b/dlls/msxml3/schema.c @@ -33,6 +33,7 @@ #include <libxml/xmlIO.h> #include <libxml/xmlversion.h> #include <libxml/xpath.h> +#include <libxml/xmlsave.h> #include "windef.h" #include "winbase.h" @@ -90,7 +91,7 @@ typedef struct { DispatchEx dispex; IXMLDOMSchemaCollection2 IXMLDOMSchemaCollection2_iface; - LONG ref; + LONG refcount; MSXML_VERSION version; xmlHashTablePtr cache; @@ -480,14 +481,15 @@ const char* debugstr_dt(XDR_DT dt) return debugstr_a(dt != DT_INVALID ? (const char*)DT_string_table[dt].x : NULL); } -HRESULT dt_validate(XDR_DT dt, xmlChar const* content) +HRESULT dt_validate(XDR_DT dt, const WCHAR *contentW) { xmlDocPtr tmp_doc; + xmlChar *content; xmlNodePtr node; xmlNsPtr ns; HRESULT hr; - TRACE("(dt:%s, %s)\n", debugstr_dt(dt), debugstr_a((char const*)content)); + TRACE("(dt:%s, %s)\n", debugstr_dt(dt), debugstr_w(contentW)); if (!datatypes_schema) { @@ -540,8 +542,10 @@ HRESULT dt_validate(XDR_DT dt, xmlChar const* content) return S_OK; } - if (content && xmlStrlen(content)) + if (contentW && *contentW) { + content = xmlchar_from_wchar(contentW); + tmp_doc = xmlNewDoc(NULL); node = xmlNewChild((xmlNodePtr)tmp_doc, NULL, dt_to_str(dt), content); ns = xmlNewNs(node, DT_nsURI, BAD_CAST "dt"); @@ -550,6 +554,8 @@ HRESULT dt_validate(XDR_DT dt, xmlChar const* content) hr = Schema_validate_tree(datatypes_schema, (xmlNodePtr)tmp_doc); xmlFreeDoc(tmp_doc); + + free(content); } else { /* probably the node is being created manually and has no content yet */ @@ -661,14 +667,11 @@ static LONG cache_entry_release(cache_entry* entry) { if (entry->type == CacheEntryType_XSD) { - xmldoc_release(entry->doc); entry->schema->doc = NULL; xmlSchemaFree(entry->schema); } else if (entry->type == CacheEntryType_XDR) { - xmldoc_release(entry->doc); - xmldoc_release(entry->schema->doc); entry->schema->doc = NULL; xmlSchemaFree(entry->schema); } @@ -761,9 +764,7 @@ static cache_entry* cache_entry_from_xsd_doc(xmlDocPtr doc, xmlChar const* nsURI if ((entry->schema = Schema_parse(spctx))) { - xmldoc_init(entry->schema->doc, v); entry->doc = entry->schema->doc; - xmldoc_add_ref(entry->doc); } else { @@ -791,10 +792,6 @@ static cache_entry* cache_entry_from_xdr_doc(xmlDocPtr doc, xmlChar const* nsURI if ((entry->schema = Schema_parse(spctx))) { entry->doc = new_doc; - xmldoc_init(entry->schema->doc, version); - xmldoc_init(entry->doc, version); - xmldoc_add_ref(entry->doc); - xmldoc_add_ref(entry->schema->doc); } else { @@ -809,35 +806,41 @@ static cache_entry* cache_entry_from_xdr_doc(xmlDocPtr doc, xmlChar const* nsURI return entry; } -static cache_entry* cache_entry_from_url(VARIANT url, xmlChar const* nsURI, MSXML_VERSION version) +static HRESULT cache_entry_on_data_available(void *obj, char *ptr, DWORD len) { - cache_entry* entry; - IXMLDOMDocument3* domdoc = NULL; - xmlDocPtr doc = NULL; - HRESULT hr = dom_document_create(version, (void **)&domdoc); - VARIANT_BOOL b = VARIANT_FALSE; - CacheEntryType type = CacheEntryType_Invalid; + xmlDocPtr *doc = obj; - if (hr != S_OK) + if ((!(*doc = xmlParseMemory(ptr, len)))) { - FIXME("failed to create domdoc\n"); - return NULL; + WARN("Failed to parse a document.\n"); + return E_FAIL; } - assert(domdoc != NULL); - assert(V_VT(&url) == VT_BSTR); - hr = IXMLDOMDocument3_load(domdoc, url, &b); - if (hr != S_OK) + return S_OK; +} + +static cache_entry* cache_entry_from_url(const WCHAR *url, xmlChar const* nsURI, MSXML_VERSION version) +{ + CacheEntryType type = CacheEntryType_Invalid; + xmlDocPtr doc = NULL; + cache_entry* entry; + IMoniker *moniker; + HRESULT hr; + bsc_t *bsc; + + if (FAILED(hr = create_moniker_from_url(url, &moniker))) { - ERR("load() returned %#lx.\n", hr); - if (b != VARIANT_TRUE) - { - FIXME("Failed to load doc at %s\n", debugstr_w(V_BSTR(&url))); - IXMLDOMDocument3_Release(domdoc); - return NULL; - } + WARN("Failed to create a url moniker, hr %#lx.\n", hr); + return NULL; } - doc = xmlNodePtr_from_domnode((IXMLDOMNode*)domdoc, XML_DOCUMENT_NODE)->doc; + + hr = bind_url(moniker, cache_entry_on_data_available, &doc, &bsc); + IMoniker_Release(moniker); + if (FAILED(hr)) + return NULL; + + detach_bsc(bsc); + type = cache_type_from_xmlDocPtr(doc); switch (type) @@ -853,7 +856,8 @@ static cache_entry* cache_entry_from_url(VARIANT url, xmlChar const* nsURI, MSXM FIXME("invalid schema\n"); break; } - IXMLDOMDocument3_Release(domdoc); + + xmlFreeDoc(doc); return entry; } @@ -912,22 +916,35 @@ static void cache_remove_entry(schema_cache *cache, const xmlChar *uri) } } +static xmlDocPtr create_xmldoc_for_text(BSTR xml) +{ + xmlChar *str = xmlchar_from_wchar(xml); + xmlDocPtr doc; + + doc = xmlParseMemory((const char *)str, xmlStrlen(str)); + free(str); + return doc; +} + /* This one adds all namespaces defined in document to a cache, without anything associated with uri obviously. Unfortunately namespace:: axis implementation in libxml2 differs from what we need, it uses additional node type to describe namespace definition attribute while in msxml it's expected to be a normal attribute - as a workaround document is queried at libxml2 level here. */ -HRESULT cache_from_doc_ns(IXMLDOMSchemaCollection2 *iface, xmlnode *node) +HRESULT cache_from_doc_ns(IXMLDOMSchemaCollection2 *iface, struct domnode *node) { schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); static const xmlChar query[] = "//*/namespace::*"; xmlXPathObjectPtr nodeset; xmlXPathContextPtr ctxt; + xmlNodePtr xmlnode; + xmlDocPtr doc; This->read_only = 1; - ctxt = xmlXPathNewContext(node->node->doc); + doc = create_xmldoc_from_domdoc(node, &xmlnode); + ctxt = xmlXPathNewContext(doc); nodeset = xmlXPathEvalExpression(query, ctxt); xmlXPathFreeContext(ctxt); @@ -966,6 +983,8 @@ HRESULT cache_from_doc_ns(IXMLDOMSchemaCollection2 *iface, xmlnode *node) xmlXPathFreeObject(nodeset); } + xmlFreeDoc(doc); + return S_OK; } @@ -1015,32 +1034,35 @@ static HRESULT WINAPI schema_cache_QueryInterface(IXMLDOMSchemaCollection2* ifac return S_OK; } -static ULONG WINAPI schema_cache_AddRef(IXMLDOMSchemaCollection2* iface) +static ULONG WINAPI schema_cache_AddRef(IXMLDOMSchemaCollection2 *iface) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - LONG ref = InterlockedIncrement(&This->ref); - TRACE("%p, refcount %ld.\n", iface, ref); - return ref; + schema_cache *cache = impl_from_IXMLDOMSchemaCollection2(iface); + LONG refcount = InterlockedIncrement(&cache->refcount); + + TRACE("%p, refcount %ld.\n", iface, refcount); + + return refcount; } static ULONG WINAPI schema_cache_Release(IXMLDOMSchemaCollection2* iface) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - LONG ref = InterlockedDecrement(&This->ref); - TRACE("%p, refcount %ld.\n", iface, ref); + schema_cache *cache = impl_from_IXMLDOMSchemaCollection2(iface); + LONG refcount = InterlockedDecrement(&cache->refcount); + + TRACE("%p, refcount %ld.\n", iface, refcount); - if (!ref) + if (!refcount) { int i; - for (i = 0; i < This->count; i++) - free(This->uris[i]); - free(This->uris); - xmlHashFree(This->cache, cache_free); - free(This); + for (i = 0; i < cache->count; i++) + free(cache->uris[i]); + free(cache->uris); + xmlHashFree(cache->cache, cache_free); + free(cache); } - return ref; + return refcount; } static HRESULT WINAPI schema_cache_GetTypeInfoCount(IXMLDOMSchemaCollection2* iface, @@ -1080,12 +1102,12 @@ static HRESULT WINAPI schema_cache_Invoke(IXMLDOMSchemaCollection2* iface, static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri, VARIANT var) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); + schema_cache *cache = impl_from_IXMLDOMSchemaCollection2(iface); xmlChar* name; - TRACE("(%p)->(%s %s)\n", This, debugstr_w(uri), debugstr_variant(&var)); + TRACE("%p, %s, %s.\n", iface, debugstr_w(uri), debugstr_variant(&var)); - if (This->read_only) return E_FAIL; + if (cache->read_only) return E_FAIL; name = uri ? xmlchar_from_wchar(uri) : xmlchar_from_wchar(emptyW); @@ -1093,13 +1115,13 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri { case VT_NULL: { - cache_remove_entry(This, name); + cache_remove_entry(cache, name); } break; case VT_BSTR: { - cache_entry* entry = cache_entry_from_url(var, name, This->version); + cache_entry* entry = cache_entry_from_url(V_BSTR(&var), name, cache->version); if (entry) { @@ -1111,7 +1133,7 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri return E_FAIL; } - cache_add_entry(This, name, entry); + cache_add_entry(cache, name, entry); } break; @@ -1122,6 +1144,9 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri cache_entry* entry; CacheEntryType type; IXMLDOMNode* domnode = NULL; + IXMLDOMDocument *domdoc; + BSTR xml; + IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_IXMLDOMNode, (void**)&domnode); if (domnode) @@ -1129,50 +1154,44 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri DOMNodeType type; IXMLDOMNode_get_nodeType(domnode, &type); - switch (type) - { - case NODE_ELEMENT: + if (type == NODE_ELEMENT || type == NODE_DOCUMENT) { - IXMLDOMDocument *domdoc; - VARIANT_BOOL b; - BSTR xml; - IXMLDOMNode_get_xml(domnode, &xml); - dom_document_create(This->version, (void **)&domdoc); - IXMLDOMDocument_loadXML(domdoc, xml, &b); - SysFreeString(xml); - doc = xmlNodePtr_from_domnode((IXMLDOMNode*)domdoc, XML_DOCUMENT_NODE)->doc; - break; } - default: - doc = xmlNodePtr_from_domnode(domnode, XML_DOCUMENT_NODE)->doc; - break; + else + { + IXMLDOMNode_get_ownerDocument(domnode, &domdoc); + IXMLDOMDocument_get_xml(domdoc, &xml); + IXMLDOMDocument_Release(domdoc); } + + IXMLDOMNode_Release(domnode); + + doc = create_xmldoc_for_text(xml); + SysFreeString(xml); } if (!doc) { - IXMLDOMNode_Release(domnode); free(name); return E_INVALIDARG; } - type = cache_type_from_xmlDocPtr(doc); + type = cache_type_from_xmlDocPtr(doc); if (type == CacheEntryType_XSD) { - entry = cache_entry_from_xsd_doc(doc, name, This->version); + entry = cache_entry_from_xsd_doc(doc, name, cache->version); } else if (type == CacheEntryType_XDR) { - entry = cache_entry_from_xdr_doc(doc, name, This->version); + entry = cache_entry_from_xdr_doc(doc, name, cache->version); } else { WARN("invalid schema!\n"); entry = NULL; } - - IXMLDOMNode_Release(domnode); + xmlFreeDoc(doc); if (entry) { @@ -1184,7 +1203,7 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri return E_FAIL; } - cache_add_entry(This, name, entry); + cache_add_entry(cache, name, entry); } break; @@ -1200,13 +1219,15 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri static HRESULT WINAPI schema_cache_get(IXMLDOMSchemaCollection2* iface, BSTR uri, IXMLDOMNode** node) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); + schema_cache *cache = impl_from_IXMLDOMSchemaCollection2(iface); cache_entry* entry; xmlChar* name; + HRESULT hr; + VARIANT v; - TRACE("(%p)->(%s %p)\n", This, debugstr_w(uri), node); + TRACE("%p, %s, %p.\n", iface, debugstr_w(uri), node); - if (This->version == MSXML6) + if (cache->version == MSXML6) { if (node) *node = NULL; return E_NOTIMPL; @@ -1218,40 +1239,68 @@ static HRESULT WINAPI schema_cache_get(IXMLDOMSchemaCollection2* iface, BSTR uri *node = NULL; name = uri ? xmlchar_from_wchar(uri) : xmlchar_from_wchar(emptyW); - entry = (cache_entry*) xmlHashLookup(This->cache, name); + entry = (cache_entry *) xmlHashLookup(cache->cache, name); free(name); /* TODO: this should be read-only */ if (entry && entry->doc) - return get_domdoc_from_xmldoc(entry->doc, (IXMLDOMDocument3**)node); + { + ISequentialStream *stream; + IXMLDOMDocument *doc; + xmlBufferPtr buffer; + xmlSaveCtxtPtr save; + VARIANT_BOOL b; + + buffer = xmlBufferCreate(); + save = xmlSaveToBuffer(buffer, "UTF-8", 0); + xmlSaveDoc(save, entry->doc); + + dom_document_create(cache->version, (void **)&doc); + if (SUCCEEDED(hr = stream_wrapper_create(xmlBufferContent(buffer), xmlBufferLength(buffer), &stream))) + { + V_VT(&v) = VT_UNKNOWN; + V_UNKNOWN(&v) = (IUnknown *)stream; + hr = IXMLDOMDocument_load(doc, v, &b); + ISequentialStream_Release(stream); + } + + xmlSaveClose(save); + xmlBufferFree(buffer); + + hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void **)node); + IXMLDOMDocument_Release(doc); + + return hr; + } return S_OK; } -static HRESULT WINAPI schema_cache_remove(IXMLDOMSchemaCollection2* iface, BSTR uri) +static HRESULT WINAPI schema_cache_remove(IXMLDOMSchemaCollection2 *iface, BSTR uri) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - xmlChar* name; + schema_cache *cache = impl_from_IXMLDOMSchemaCollection2(iface); + xmlChar *name; - TRACE("(%p)->(%s)\n", This, debugstr_w(uri)); + TRACE("%p, %s.\n", iface, debugstr_w(uri)); - if (This->version == MSXML6) return E_NOTIMPL; + if (cache->version == MSXML6) return E_NOTIMPL; name = uri ? xmlchar_from_wchar(uri) : xmlchar_from_wchar(emptyW); - cache_remove_entry(This, name); + cache_remove_entry(cache, name); free(name); return S_OK; } -static HRESULT WINAPI schema_cache_get_length(IXMLDOMSchemaCollection2* iface, LONG* length) +static HRESULT WINAPI schema_cache_get_length(IXMLDOMSchemaCollection2 *iface, LONG *length) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - TRACE("(%p)->(%p)\n", This, length); + schema_cache *cache = impl_from_IXMLDOMSchemaCollection2(iface); + + TRACE("%p, %p.\n", iface, length); if (!length) return E_POINTER; - *length = This->count; + *length = cache->count; return S_OK; } @@ -1287,13 +1336,13 @@ static void cache_copy(void* data, void* dest, const xmlChar* name) } } -static HRESULT WINAPI schema_cache_addCollection(IXMLDOMSchemaCollection2* iface, - IXMLDOMSchemaCollection* collection) +static HRESULT WINAPI schema_cache_addCollection(IXMLDOMSchemaCollection2 *iface, + IXMLDOMSchemaCollection *collection) { schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); schema_cache* That; - TRACE("(%p)->(%p)\n", This, collection); + TRACE("%p, %p.\n", iface, collection); if (!collection) return E_POINTER; @@ -1311,17 +1360,17 @@ static HRESULT WINAPI schema_cache_addCollection(IXMLDOMSchemaCollection2* iface return S_OK; } -static HRESULT WINAPI schema_cache_get__newEnum(IXMLDOMSchemaCollection2* iface, IUnknown** enumv) +static HRESULT WINAPI schema_cache_get__newEnum(IXMLDOMSchemaCollection2 *iface, IUnknown **enumv) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - TRACE("(%p)->(%p)\n", This, enumv); - return create_enumvariant((IUnknown*)iface, TRUE, &schemacache_enumvariant, (IEnumVARIANT**)enumv); + TRACE("%p, %p.\n", iface, enumv); + + return create_enumvariant((IUnknown *)iface, TRUE, &schemacache_enumvariant, (IEnumVARIANT **)enumv); } static HRESULT WINAPI schema_cache_validate(IXMLDOMSchemaCollection2* iface) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - FIXME("(%p): stub\n", This); + FIXME("%p: stub\n", iface); + return E_NOTIMPL; } @@ -1338,33 +1387,31 @@ static HRESULT WINAPI schema_cache_put_validateOnLoad(IXMLDOMSchemaCollection2* return E_NOTIMPL; } -static HRESULT WINAPI schema_cache_get_validateOnLoad(IXMLDOMSchemaCollection2* iface, - VARIANT_BOOL* value) +static HRESULT WINAPI schema_cache_get_validateOnLoad(IXMLDOMSchemaCollection2 *iface, VARIANT_BOOL *value) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - TRACE("(%p)->(%p)\n", This, value); + schema_cache *cache = impl_from_IXMLDOMSchemaCollection2(iface); + + TRACE("%p, %p.\n", iface, value); if (!value) return E_POINTER; - *value = This->validateOnLoad; + *value = cache->validateOnLoad; return S_OK; } -static HRESULT WINAPI schema_cache_getSchema(IXMLDOMSchemaCollection2* iface, - BSTR namespaceURI, ISchema** schema) +static HRESULT WINAPI schema_cache_getSchema(IXMLDOMSchemaCollection2 *iface, BSTR namespaceURI, ISchema **schema) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(namespaceURI), schema); + FIXME("%p, %s, %p: stub\n", iface, debugstr_w(namespaceURI), schema); + if (schema) *schema = NULL; return E_NOTIMPL; } -static HRESULT WINAPI schema_cache_getDeclaration(IXMLDOMSchemaCollection2* iface, - IXMLDOMNode* node, ISchemaItem** item) +static HRESULT WINAPI schema_cache_getDeclaration(IXMLDOMSchemaCollection2 *iface, IXMLDOMNode *node, ISchemaItem **item) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - FIXME("(%p)->(%p %p): stub\n", This, node, item); + FIXME("%p, %p, %p: stub\n", iface, node, item); + if (item) *item = NULL; return E_NOTIMPL; @@ -1393,15 +1440,15 @@ static const struct IXMLDOMSchemaCollection2Vtbl XMLDOMSchemaCollection2Vtbl = schema_cache_getDeclaration }; -static xmlSchemaElementPtr lookup_schema_elemDecl(xmlSchemaPtr schema, xmlNodePtr node) +static xmlSchemaElementPtr lookup_schema_elemDecl(xmlSchemaPtr schema, const xmlChar *name, const xmlChar *uri) { xmlSchemaElementPtr decl = NULL; - xmlChar const* nsURI = get_node_nsURI(node); + xmlChar const* nsURI = uri; - TRACE("(%p, %p)\n", schema, node); + TRACE("%p, %s, %s.\n", schema, debugstr_a((const char *)name), debugstr_a((const char *)uri)); if (xmlStrEqual(nsURI, schema->targetNamespace)) - decl = xmlHashLookup(schema->elemDecl, node->name); + decl = xmlHashLookup(schema->elemDecl, name); if (!decl && xmlHashSize(schema->schemasImports) > 1) { @@ -1419,9 +1466,9 @@ static xmlSchemaElementPtr lookup_schema_elemDecl(xmlSchemaPtr schema, xmlNodePt return decl; } -static inline xmlNodePtr lookup_schema_element(xmlSchemaPtr schema, xmlNodePtr node) +static inline xmlNodePtr lookup_schema_element(xmlSchemaPtr schema, const xmlChar *name, const xmlChar *uri) { - xmlSchemaElementPtr decl = lookup_schema_elemDecl(schema, node); + xmlSchemaElementPtr decl = lookup_schema_elemDecl(schema, name, uri); while (decl != NULL && decl->refDecl != NULL) decl = decl->refDecl; return (decl != NULL)? decl->node : NULL; @@ -1451,22 +1498,30 @@ HRESULT SchemaCache_validate_tree(IXMLDOMSchemaCollection2* iface, xmlNodePtr tr return E_FAIL; } -XDR_DT SchemaCache_get_node_dt(IXMLDOMSchemaCollection2* iface, xmlNodePtr node) +XDR_DT SchemaCache_get_node_dt(IXMLDOMSchemaCollection2* iface, const WCHAR *nameW, const WCHAR *uriW) { - schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - xmlSchemaPtr schema = get_node_schema(This, node); + schema_cache *cache = impl_from_IXMLDOMSchemaCollection2(iface); + xmlSchemaPtr schema = NULL; XDR_DT dt = DT_INVALID; + xmlChar *uri, *name; + cache_entry *entry; + + TRACE("%p, %s, %s.\n", cache, debugstr_w(nameW), debugstr_w(uriW)); - TRACE("(%p, %p)\n", This, node); + uri = uriW ? xmlchar_from_wchar(uriW) : NULL; + name = xmlchar_from_wchar(nameW); - if (node->ns && xmlStrEqual(node->ns->href, DT_nsURI)) + if ((entry = get_entry(cache, uri))) + schema = entry->schema; + + if (uri && xmlStrEqual(uri, DT_nsURI)) { - dt = str_to_dt(node->name, -1); + dt = str_to_dt(name, -1); } else if (schema) { xmlChar* str; - xmlNodePtr schema_node = lookup_schema_element(schema, node); + xmlNodePtr schema_node = lookup_schema_element(schema, name, uri); str = xmlGetNsProp(schema_node, BAD_CAST "dt", DT_nsURI); if (str) @@ -1476,40 +1531,45 @@ XDR_DT SchemaCache_get_node_dt(IXMLDOMSchemaCollection2* iface, xmlNodePtr node) } } + free(uri); + free(name); + return dt; } -static const tid_t schemacache_iface_tids[] = { +static const tid_t schemacache_iface_tids[] = +{ IXMLDOMSchemaCollection2_tid, 0 }; -static dispex_static_data_t schemacache_dispex = { +static dispex_static_data_t schemacache_dispex = +{ NULL, IXMLDOMSchemaCollection2_tid, NULL, schemacache_iface_tids }; -HRESULT SchemaCache_create(MSXML_VERSION version, void** obj) +HRESULT SchemaCache_create(MSXML_VERSION version, void **ret) { - schema_cache* This = malloc(sizeof(schema_cache)); - if (!This) + schema_cache *object; + + TRACE("%d, %p.\n", version, ret); + + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; - TRACE("(%d %p)\n", version, obj); + object->IXMLDOMSchemaCollection2_iface.lpVtbl = &XMLDOMSchemaCollection2Vtbl; + object->cache = xmlHashCreate(DEFAULT_HASHTABLE_SIZE); + object->allocated = 10; + object->uris = malloc(object->allocated * sizeof(xmlChar*)); + object->refcount = 1; + object->version = version; + object->validateOnLoad = VARIANT_TRUE; + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMSchemaCollection2_iface, &schemacache_dispex); - This->IXMLDOMSchemaCollection2_iface.lpVtbl = &XMLDOMSchemaCollection2Vtbl; - This->cache = xmlHashCreate(DEFAULT_HASHTABLE_SIZE); - This->allocated = 10; - This->count = 0; - This->uris = malloc(This->allocated * sizeof(xmlChar*)); - This->ref = 1; - This->version = version; - This->validateOnLoad = VARIANT_TRUE; - This->read_only = 0; - init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMSchemaCollection2_iface, &schemacache_dispex); + *ret = &object->IXMLDOMSchemaCollection2_iface; - *obj = &This->IXMLDOMSchemaCollection2_iface; return S_OK; } diff --git a/dlls/msxml3/selection.c b/dlls/msxml3/selection.c index e752f59b347..789a3ac2a33 100644 --- a/dlls/msxml3/selection.c +++ b/dlls/msxml3/selection.c @@ -27,6 +27,7 @@ #include <libxml/xmlerror.h> #include <libxml/xpath.h> #include <libxml/xpathInternals.h> +#include <libxml/xmlsave.h> #include "windef.h" #include "winbase.h" @@ -50,7 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); -int registerNamespaces(xmlXPathContextPtr ctxt); +int registerNamespaces(struct domnode *node, xmlXPathContextPtr ctxt); xmlChar* XSLPattern_to_XPath(xmlXPathContextPtr ctxt, xmlChar const* xslpat_str); typedef struct @@ -66,14 +67,22 @@ typedef struct const struct enumvariant_funcs *funcs; } enumvariant; +struct selected_list +{ + struct domnode **nodes; + LONG count; + LONG pos; +}; + typedef struct { DispatchEx dispex; IXMLDOMSelection IXMLDOMSelection_iface; - LONG ref; - xmlNodePtr node; - xmlXPathObjectPtr result; - int resultPos; + LONG refcount; + struct domnode *node; + + struct selected_list result; + IEnumVARIANT *enumvariant; } domselection; @@ -91,7 +100,8 @@ static HRESULT selection_next(IUnknown *iface) return hr; } -static const struct enumvariant_funcs selection_enumvariant = { +static const struct enumvariant_funcs selection_enumvariant = +{ selection_get_item, selection_next }; @@ -106,304 +116,245 @@ static inline enumvariant *impl_from_IEnumVARIANT( IEnumVARIANT *iface ) return CONTAINING_RECORD(iface, enumvariant, IEnumVARIANT_iface); } -static HRESULT WINAPI domselection_QueryInterface( - IXMLDOMSelection *iface, - REFIID riid, - void** ppvObject ) +static HRESULT WINAPI domselection_QueryInterface(IXMLDOMSelection *iface, REFIID riid, void **obj) { - domselection *This = impl_from_IXMLDOMSelection( iface ); + domselection *selection = impl_from_IXMLDOMSelection(iface); - TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); - if(!ppvObject) + if (!obj) return E_INVALIDARG; - if ( IsEqualGUID( riid, &IID_IUnknown ) || - IsEqualGUID( riid, &IID_IXMLDOMNodeList ) || - IsEqualGUID( riid, &IID_IXMLDOMSelection )) + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IXMLDOMNodeList) || + IsEqualGUID(riid, &IID_IXMLDOMSelection)) { - *ppvObject = &This->IXMLDOMSelection_iface; + *obj = &selection->IXMLDOMSelection_iface; } - else if (IsEqualGUID( riid, &IID_IEnumVARIANT )) + else if (IsEqualGUID(riid, &IID_IEnumVARIANT)) { - if (!This->enumvariant) + if (!selection->enumvariant) { - HRESULT hr = create_enumvariant((IUnknown*)iface, FALSE, &selection_enumvariant, &This->enumvariant); + HRESULT hr = create_enumvariant((IUnknown *)iface, FALSE, &selection_enumvariant, &selection->enumvariant); if (FAILED(hr)) return hr; } - return IEnumVARIANT_QueryInterface(This->enumvariant, &IID_IEnumVARIANT, ppvObject); + return IEnumVARIANT_QueryInterface(selection->enumvariant, &IID_IEnumVARIANT, obj); } - else if (dispex_query_interface(&This->dispex, riid, ppvObject)) + else if (dispex_query_interface(&selection->dispex, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } else { TRACE("interface %s not implemented\n", debugstr_guid(riid)); - *ppvObject = NULL; + *obj = NULL; return E_NOINTERFACE; } - IXMLDOMSelection_AddRef( iface ); + IXMLDOMSelection_AddRef(iface); return S_OK; } -static ULONG WINAPI domselection_AddRef( - IXMLDOMSelection *iface ) +static ULONG WINAPI domselection_AddRef(IXMLDOMSelection *iface) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - ULONG ref = InterlockedIncrement( &This->ref ); - TRACE("%p, refcount %lu.\n", iface, ref); - return ref; + domselection *selection = impl_from_IXMLDOMSelection(iface); + ULONG refcount = InterlockedIncrement(&selection->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); + + return refcount; } -static ULONG WINAPI domselection_Release( - IXMLDOMSelection *iface ) +static ULONG WINAPI domselection_Release(IXMLDOMSelection *iface) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - ULONG ref = InterlockedDecrement(&This->ref); + domselection *selection = impl_from_IXMLDOMSelection(iface); + ULONG refcount = InterlockedDecrement(&selection->refcount); - TRACE("%p, refcount %lu.\n", iface, ref); - if ( ref == 0 ) + TRACE("%p, refcount %lu.\n", iface, refcount); + + if (!refcount) { - xmlXPathFreeObject(This->result); - if (This->node) - xmldoc_release(This->node->doc); - if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant); - free(This); + if (selection->enumvariant) + IEnumVARIANT_Release(selection->enumvariant); + + for (int i = 0; i < selection->result.count; ++i) + domnode_release(selection->result.nodes[i]); + free(selection->result.nodes); + free(selection); } - return ref; + return refcount; } -static HRESULT WINAPI domselection_GetTypeInfoCount( - IXMLDOMSelection *iface, - UINT* pctinfo ) +static HRESULT WINAPI domselection_GetTypeInfoCount(IXMLDOMSelection *iface, UINT *count) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); + domselection *selection = impl_from_IXMLDOMSelection(iface); + return IDispatchEx_GetTypeInfoCount(&selection->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI domselection_GetTypeInfo( - IXMLDOMSelection *iface, - UINT iTInfo, - LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI domselection_GetTypeInfo(IXMLDOMSelection *iface, UINT index, LCID lcid, ITypeInfo **ti) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + domselection *selection = impl_from_IXMLDOMSelection(iface); + return IDispatchEx_GetTypeInfo(&selection->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI domselection_GetIDsOfNames( - IXMLDOMSelection *iface, - REFIID riid, - LPOLESTR* rgszNames, - UINT cNames, - LCID lcid, - DISPID* rgDispId ) +static HRESULT WINAPI domselection_GetIDsOfNames(IXMLDOMSelection *iface, REFIID riid, LPOLESTR *names, + UINT name_count, LCID lcid, DISPID *dispid) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, - riid, rgszNames, cNames, lcid, rgDispId); + domselection *selection = impl_from_IXMLDOMSelection(iface); + return IDispatchEx_GetIDsOfNames(&selection->dispex.IDispatchEx_iface, riid, names, name_count, lcid, dispid); } -static HRESULT WINAPI domselection_Invoke( - IXMLDOMSelection *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS* pDispParams, - VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, - UINT* puArgErr ) +static HRESULT WINAPI domselection_Invoke(IXMLDOMSelection *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *argerr) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, - dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + domselection *selection = impl_from_IXMLDOMSelection(iface); + return IDispatchEx_Invoke(&selection->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, flags, + params, result, ei, argerr); } -static HRESULT WINAPI domselection_get_item( - IXMLDOMSelection* iface, - LONG index, - IXMLDOMNode** listItem) +static HRESULT WINAPI domselection_get_item(IXMLDOMSelection *iface, LONG index, IXMLDOMNode **item) { - domselection *This = impl_from_IXMLDOMSelection( iface ); + domselection *selection = impl_from_IXMLDOMSelection(iface); - TRACE("%p, %ld, %p.\n", iface, index, listItem); + TRACE("%p, %ld, %p.\n", iface, index, item); - if(!listItem) + if (!item) return E_INVALIDARG; - *listItem = NULL; + *item = NULL; - if (index < 0 || index >= xmlXPathNodeSetGetLength(This->result->nodesetval)) + if (index < 0 || index >= selection->result.count) return S_FALSE; - *listItem = create_node(xmlXPathNodeSetItem(This->result->nodesetval, index)); - This->resultPos = index + 1; + selection->result.pos = index + 1; - return S_OK; + return create_node(selection->result.nodes[index], item); } -static HRESULT WINAPI domselection_get_length( - IXMLDOMSelection* iface, - LONG* listLength) +static HRESULT WINAPI domselection_get_length(IXMLDOMSelection *iface, LONG *length) { - domselection *This = impl_from_IXMLDOMSelection( iface ); + domselection *selection = impl_from_IXMLDOMSelection(iface); - TRACE("(%p)->(%p)\n", This, listLength); + TRACE("%p, %p.\n", iface, length); - if(!listLength) + if (!length) return E_INVALIDARG; - *listLength = xmlXPathNodeSetGetLength(This->result->nodesetval); + *length = selection->result.count; return S_OK; } -static HRESULT WINAPI domselection_nextNode( - IXMLDOMSelection* iface, - IXMLDOMNode** nextItem) +static HRESULT WINAPI domselection_nextNode(IXMLDOMSelection *iface, IXMLDOMNode **node) { - domselection *This = impl_from_IXMLDOMSelection( iface ); + domselection *selection = impl_from_IXMLDOMSelection(iface); - TRACE("(%p)->(%p)\n", This, nextItem ); + TRACE("%p, %p.\n", iface, node); - if(!nextItem) + if (!node) return E_INVALIDARG; - *nextItem = NULL; + *node = NULL; - if (This->resultPos >= xmlXPathNodeSetGetLength(This->result->nodesetval)) + if (selection->result.pos >= selection->result.count) return S_FALSE; - *nextItem = create_node(xmlXPathNodeSetItem(This->result->nodesetval, This->resultPos)); - This->resultPos++; - return S_OK; + return create_node(selection->result.nodes[selection->result.pos++], node); } -static HRESULT WINAPI domselection_reset( - IXMLDOMSelection* iface) +static HRESULT WINAPI domselection_reset(IXMLDOMSelection *iface) { - domselection *This = impl_from_IXMLDOMSelection( iface ); + domselection *selection = impl_from_IXMLDOMSelection(iface); - TRACE("%p\n", This); - This->resultPos = 0; + TRACE("%p.\n", iface); + + selection->result.pos = 0; return S_OK; } -static HRESULT WINAPI domselection_get__newEnum( - IXMLDOMSelection* iface, - IUnknown** enumv) +static HRESULT WINAPI domselection_get__newEnum(IXMLDOMSelection *iface, IUnknown **enumv) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - - TRACE("(%p)->(%p)\n", This, enumv); + TRACE("%p, %p.\n", iface, enumv); - return create_enumvariant((IUnknown*)iface, TRUE, &selection_enumvariant, (IEnumVARIANT**)enumv); + return create_enumvariant((IUnknown *)iface, TRUE, &selection_enumvariant, (IEnumVARIANT**)enumv); } -static HRESULT WINAPI domselection_get_expr( - IXMLDOMSelection* iface, - BSTR *p) +static HRESULT WINAPI domselection_get_expr(IXMLDOMSelection *iface, BSTR *p) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - FIXME("(%p)->(%p)\n", This, p); + FIXME("%p, %p.\n", iface, p); + return E_NOTIMPL; } -static HRESULT WINAPI domselection_put_expr( - IXMLDOMSelection* iface, - BSTR p) +static HRESULT WINAPI domselection_put_expr(IXMLDOMSelection *iface, BSTR p) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - FIXME("(%p)->(%s)\n", This, debugstr_w(p)); + FIXME("%p, %s.\n", iface, debugstr_w(p)); + return E_NOTIMPL; } -static HRESULT WINAPI domselection_get_context( - IXMLDOMSelection* iface, - IXMLDOMNode **node) +static HRESULT WINAPI domselection_get_context(IXMLDOMSelection *iface, IXMLDOMNode **node) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - FIXME("(%p)->(%p)\n", This, node); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domselection_putref_context( - IXMLDOMSelection* iface, - IXMLDOMNode *node) +static HRESULT WINAPI domselection_putref_context(IXMLDOMSelection *iface, IXMLDOMNode *node) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - FIXME("(%p)->(%p)\n", This, node); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domselection_peekNode( - IXMLDOMSelection* iface, - IXMLDOMNode **node) +static HRESULT WINAPI domselection_peekNode(IXMLDOMSelection *iface, IXMLDOMNode **node) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - FIXME("(%p)->(%p)\n", This, node); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domselection_matches( - IXMLDOMSelection* iface, - IXMLDOMNode *node, - IXMLDOMNode **out_node) +static HRESULT WINAPI domselection_matches(IXMLDOMSelection *iface, IXMLDOMNode *node, IXMLDOMNode **out_node) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - FIXME("(%p)->(%p %p)\n", This, node, out_node); + FIXME("%p, %p, %p.\n", iface, node, out_node); + return E_NOTIMPL; } -static HRESULT WINAPI domselection_removeNext( - IXMLDOMSelection* iface, - IXMLDOMNode **node) +static HRESULT WINAPI domselection_removeNext(IXMLDOMSelection *iface, IXMLDOMNode **node) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - FIXME("(%p)->(%p)\n", This, node); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domselection_removeAll( - IXMLDOMSelection* iface) +static HRESULT WINAPI domselection_removeAll(IXMLDOMSelection *iface) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - FIXME("(%p)\n", This); + FIXME("%p.\n", iface); + return E_NOTIMPL; } -static HRESULT WINAPI domselection_clone( - IXMLDOMSelection* iface, - IXMLDOMSelection **node) +static HRESULT WINAPI domselection_clone(IXMLDOMSelection *iface, IXMLDOMSelection **node) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - FIXME("(%p)->(%p)\n", This, node); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domselection_getProperty( - IXMLDOMSelection* iface, - BSTR p, - VARIANT *var) +static HRESULT WINAPI domselection_getProperty(IXMLDOMSelection *iface, BSTR p, VARIANT *var) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - FIXME("(%p)->(%s %p)\n", This, debugstr_w(p), var); + FIXME("%p, %s, %p.\n", iface, debugstr_w(p), var); + return E_NOTIMPL; } -static HRESULT WINAPI domselection_setProperty( - IXMLDOMSelection* iface, - BSTR p, - VARIANT var) +static HRESULT WINAPI domselection_setProperty(IXMLDOMSelection *iface, BSTR p, VARIANT var) { - domselection *This = impl_from_IXMLDOMSelection( iface ); - FIXME("(%p)->(%s %s)\n", This, debugstr_w(p), debugstr_variant(&var)); + FIXME("%p, %s, %s.\n", iface, debugstr_w(p), debugstr_variant(&var)); + return E_NOTIMPL; } @@ -434,7 +385,6 @@ static const struct IXMLDOMSelectionVtbl domselection_vtbl = domselection_setProperty }; -/* IEnumVARIANT support */ static HRESULT WINAPI enumvariant_QueryInterface( IEnumVARIANT *iface, REFIID riid, @@ -473,7 +423,7 @@ static ULONG WINAPI enumvariant_AddRef(IEnumVARIANT *iface ) return ref; } -static ULONG WINAPI enumvariant_Release(IEnumVARIANT *iface ) +static ULONG WINAPI enumvariant_Release(IEnumVARIANT *iface) { enumvariant *This = impl_from_IEnumVARIANT( iface ); ULONG ref = InterlockedDecrement(&This->ref); @@ -488,11 +438,7 @@ static ULONG WINAPI enumvariant_Release(IEnumVARIANT *iface ) return ref; } -static HRESULT WINAPI enumvariant_Next( - IEnumVARIANT *iface, - ULONG celt, - VARIANT *var, - ULONG *fetched) +static HRESULT WINAPI enumvariant_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched) { enumvariant *This = impl_from_IEnumVARIANT( iface ); ULONG ret_count = 0; @@ -526,9 +472,7 @@ static HRESULT WINAPI enumvariant_Next( return celt == 0 ? S_OK : S_FALSE; } -static HRESULT WINAPI enumvariant_Skip( - IEnumVARIANT *iface, - ULONG celt) +static HRESULT WINAPI enumvariant_Skip(IEnumVARIANT *iface, ULONG celt) { FIXME("%p, %lu: stub\n", iface, celt); @@ -544,11 +488,10 @@ static HRESULT WINAPI enumvariant_Reset(IEnumVARIANT *iface) return S_OK; } -static HRESULT WINAPI enumvariant_Clone( - IEnumVARIANT *iface, IEnumVARIANT **ppenum) +static HRESULT WINAPI enumvariant_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppenum) { - enumvariant *This = impl_from_IEnumVARIANT( iface ); - FIXME("(%p)->(%p): stub\n", This, ppenum); + FIXME("%p, %p: stub\n", iface, ppenum); + return E_NOTIMPL; } @@ -603,7 +546,7 @@ static HRESULT domselection_get_dispid(IUnknown *iface, BSTR name, DWORD flags, static HRESULT domselection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei) { - domselection *This = impl_from_IXMLDOMSelection( (IXMLDOMSelection*)iface ); + domselection *selection = impl_from_IXMLDOMSelection((IXMLDOMSelection *)iface); TRACE("%p, %ld, %lx, %x, %p, %p, %p.\n", iface, id, lcid, flags, params, res, ei); @@ -619,7 +562,7 @@ static HRESULT domselection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD f { IXMLDOMNode *disp = NULL; - IXMLDOMSelection_get_item(&This->IXMLDOMSelection_iface, id - DISPID_DOM_COLLECTION_BASE, &disp); + IXMLDOMSelection_get_item(&selection->IXMLDOMSelection_iface, id - DISPID_DOM_COLLECTION_BASE, &disp); V_DISPATCH(res) = (IDispatch*)disp; break; } @@ -635,16 +578,20 @@ static HRESULT domselection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD f return S_OK; } -static const dispex_static_data_vtbl_t domselection_dispex_vtbl = { +static const dispex_static_data_vtbl_t domselection_dispex_vtbl = +{ domselection_get_dispid, domselection_invoke }; -static const tid_t domselection_iface_tids[] = { +static const tid_t domselection_iface_tids[] = +{ IXMLDOMSelection_tid, 0 }; -static dispex_static_data_t domselection_dispex = { + +static dispex_static_data_t domselection_dispex = +{ &domselection_dispex_vtbl, IXMLDOMSelection_tid, NULL, @@ -658,7 +605,6 @@ static dispex_static_data_t domselection_dispex = { return; \ } - static void XSLPattern_index(xmlXPathParserContextPtr pctx, int nargs) { XSLPATTERN_CHECK_ARGS(0); @@ -762,43 +708,33 @@ static void query_serror(void* ctx, const xmlError* err) LIBXML2_CALLBACK_SERROR(domselection_create, err); } -HRESULT create_selection(xmlNodePtr node, xmlChar* query, IXMLDOMNodeList **out) +static HRESULT select_nodes(struct domnode *node, BSTR query, bool xpath, struct selected_list *list) { - domselection *This = malloc(sizeof(domselection)); - xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc); + xmlXPathObjectPtr result; + xmlXPathContextPtr ctxt; + xmlNodePtr xmlnode; + xmlChar *xmlquery; + xmlDocPtr xmldoc; HRESULT hr; - TRACE("(%p, %s, %p)\n", node, debugstr_a((char const*)query), out); - - *out = NULL; - if (!This || !ctxt || !query) - { - xmlXPathFreeContext(ctxt); - free(This); - return E_OUTOFMEMORY; - } + xmlquery = xmlchar_from_wchar(query); + xmldoc = create_xmldoc_from_domdoc(node, &xmlnode); - This->IXMLDOMSelection_iface.lpVtbl = &domselection_vtbl; - This->ref = 1; - This->resultPos = 0; - This->node = node; - This->enumvariant = NULL; - init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMSelection_iface, &domselection_dispex); - xmldoc_add_ref(This->node->doc); + ctxt = xmlXPathNewContext(xmldoc); + ctxt->node = xmlnode; ctxt->error = query_serror; - ctxt->node = node; - registerNamespaces(ctxt); + registerNamespaces(node, ctxt); xmlXPathContextSetCache(ctxt, 1, -1, 0); - if (is_xpathmode(This->node->doc)) + if (xpath) { xmlXPathRegisterAllFunctions(ctxt); - This->result = xmlXPathEvalExpression(query, ctxt); + result = xmlXPathEvalExpression(xmlquery, ctxt); } else { - xmlChar* pattern_query = XSLPattern_to_XPath(ctxt, query); + xmlChar* pattern_query = XSLPattern_to_XPath(ctxt, xmlquery); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"not", xmlXPathNotFunction); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"boolean", xmlXPathBooleanFunction); @@ -814,32 +750,82 @@ HRESULT create_selection(xmlNodePtr node, xmlChar* query, IXMLDOMNodeList **out) xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGt", XSLPattern_OP_IGt); xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGEq", XSLPattern_OP_IGEq); - This->result = xmlXPathEvalExpression(pattern_query, ctxt); + result = xmlXPathEvalExpression(pattern_query, ctxt); xmlFree(pattern_query); } - if (!This->result || This->result->type != XPATH_NODESET) + if (result && result->type == XPATH_NODESET) + { + list->count = xmlXPathNodeSetGetLength(result->nodesetval); + list->nodes = calloc(list->count, sizeof(*list->nodes)); + + for (int i = 0; i < list->count; ++i) + { + xmlnode = xmlXPathNodeSetItem(result->nodesetval, i); + + if (xmlnode->type == XML_NAMESPACE_DECL) + { + FIXME("Not implemented for namespace nodes.\n"); + list->count--; + continue; + } + else + { + node = xmlnode->_private2; + } + + list->nodes[i] = domnode_addref(node); + } + + TRACE("found %ld matches\n", list->count); + hr = S_OK; + } + else { hr = E_FAIL; - goto cleanup; } - *out = (IXMLDOMNodeList*)&This->IXMLDOMSelection_iface; - hr = S_OK; - TRACE("found %d matches\n", xmlXPathNodeSetGetLength(This->result->nodesetval)); - -cleanup: - if (FAILED(hr)) - IXMLDOMSelection_Release( &This->IXMLDOMSelection_iface ); + xmlXPathFreeObject(result); xmlXPathFreeContext(ctxt); + free(xmlquery); + return hr; } -HRESULT create_selection_from_nodeset(xmlXPathObjectPtr nodeset, IXMLDOMNodeList **out) +HRESULT create_selection(struct domnode *node, BSTR query, bool xpath, IXMLDOMNodeList **out) +{ + domselection *object; + HRESULT hr; + + TRACE("%p, %s, %p.\n", node, debugstr_w(query), out); + + *out = NULL; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = select_nodes(node, query, xpath, &object->result))) + { + free(object); + return hr; + } + + object->IXMLDOMSelection_iface.lpVtbl = &domselection_vtbl; + object->refcount = 1; + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMSelection_iface, &domselection_dispex); + + *out = (IXMLDOMNodeList *)&object->IXMLDOMSelection_iface; + + return S_OK; +} + +HRESULT create_selection_from_nodeset(xmlXPathObjectPtr result, IXMLDOMNodeList **out) { + struct domnode *node; + xmlNodePtr xmlnode; domselection *obj; - TRACE("%p, %p.\n", nodeset, out); + TRACE("%p, %p.\n", result, out); *out = NULL; @@ -847,10 +833,37 @@ HRESULT create_selection_from_nodeset(xmlXPathObjectPtr nodeset, IXMLDOMNodeList return E_OUTOFMEMORY; obj->IXMLDOMSelection_iface.lpVtbl = &domselection_vtbl; - obj->ref = 1; + obj->refcount = 1; init_dispex(&obj->dispex, (IUnknown *)&obj->IXMLDOMSelection_iface, &domselection_dispex); - obj->result = nodeset; + if (result && result->type == XPATH_NODESET) + { + obj->result.count = xmlXPathNodeSetGetLength(result->nodesetval); + obj->result.nodes = calloc(obj->result.count, sizeof(*obj->result.nodes)); + + for (int i = 0; i < obj->result.count; ++i) + { + xmlnode = xmlXPathNodeSetItem(result->nodesetval, i); + + if (xmlnode->type == XML_NAMESPACE_DECL) + { + FIXME("Not implemented for namespace nodes.\n"); + obj->result.count--; + continue; + } + else if (!xmlnode->_private2) + { + WARN("Skipping untracked node.\n"); + obj->result.count--; + continue; + } + else + { + node = xmlnode->_private2; + obj->result.nodes[i] = domnode_addref(node); + } + } + } *out = (IXMLDOMNodeList *)&obj->IXMLDOMSelection_iface; diff --git a/dlls/msxml3/stylesheet.c b/dlls/msxml3/stylesheet.c index 8163e9d5340..ba445746868 100644 --- a/dlls/msxml3/stylesheet.c +++ b/dlls/msxml3/stylesheet.c @@ -21,8 +21,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> #include "windef.h" #include "winbase.h" @@ -804,31 +802,28 @@ static dispex_static_data_t xslprocessor_dispex = { xslprocessor_iface_tids }; -HRESULT XSLProcessor_create(xsltemplate *template, IXSLProcessor **ppObj) +HRESULT XSLProcessor_create(xsltemplate *template, IXSLProcessor **ret) { - xslprocessor *This; + xslprocessor *object; - TRACE("(%p)\n", ppObj); + TRACE("%p.\n", ret); - This = malloc(sizeof(*This)); - if(!This) + *ret = NULL; + + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; - This->IXSLProcessor_iface.lpVtbl = &XSLProcessorVtbl; - This->ref = 1; - This->input = NULL; - This->output.unk = NULL; - This->output_type = PROCESSOR_OUTPUT_NOT_SET; - This->outstr = NULL; - list_init(&This->params.list); - This->params.count = 0; - This->stylesheet = template; + object->IXSLProcessor_iface.lpVtbl = &XSLProcessorVtbl; + object->ref = 1; + object->output_type = PROCESSOR_OUTPUT_NOT_SET; + list_init(&object->params.list); + object->stylesheet = template; IXSLTemplate_AddRef(&template->IXSLTemplate_iface); - init_dispex(&This->dispex, (IUnknown*)&This->IXSLProcessor_iface, &xslprocessor_dispex); + init_dispex(&object->dispex, (IUnknown *)&object->IXSLProcessor_iface, &xslprocessor_dispex); - *ppObj = &This->IXSLProcessor_iface; + *ret = &object->IXSLProcessor_iface; - TRACE("returning iface %p\n", *ppObj); + TRACE("returning iface %p\n", *ret); return S_OK; } diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 355268625e9..6ced8db12fa 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -3734,6 +3734,7 @@ static void test_get_text(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMElement_get_text(element, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine ok(!wcscmp(str, L" This is b"), "%s\n", debugstr_w(str)); SysFreeString(str); IXMLDOMElement_Release(element); @@ -3744,7 +3745,6 @@ static void test_get_text(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMElement_get_text(element, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L" This is"), "%s\n", debugstr_w(str)); SysFreeString(str); IXMLDOMElement_Release(element); @@ -3859,7 +3859,6 @@ static void test_get_childNodes(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(node_type == NODE_DOCUMENT_TYPE, "Unexpected node %d.\n", node_type); hr = IXMLDOMDocument_removeChild(doc, node, NULL); - todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); IXMLDOMNode_Release(node); @@ -3873,7 +3872,6 @@ static void test_get_childNodes(void) IXMLDOMNode_Release(node); hr = IXMLDOMNodeList_get_length(node_list, &len); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(len == 1, "Unexpected length %ld.\n", len); hr = IXMLDOMDocument_get_documentElement(doc, &element); @@ -4908,12 +4906,14 @@ static void test_IXMLDOMDocument2(void) ok( b == VARIANT_TRUE, "failed to load XML string\n"); err = NULL; hr = IXMLDOMDocument2_validate(dtddoc2, &err); + todo_wine ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr); ok(err != NULL, "expected pointer\n"); if (err) { res = 0; hr = IXMLDOMParseError_get_errorCode(err, &res); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); /* XML_REQUIRED_ATTRIBUTE_MISSING */ todo_wine ok(res == 0xC00CE020, "Unexpected code %#lx.\n", res); @@ -5900,10 +5900,8 @@ static void test_cloneNode(void ) hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocument2, (void **)&doc_clone); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMDocument2_get_doctype(doc_clone, &doctype2); - todo_wine ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr ); hr = IXMLDOMDocument2_get_documentElement(doc_clone, &element); - todo_wine ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr); IXMLDOMDocument2_Release(doc_clone); IXMLDOMNode_Release(node); @@ -6720,7 +6718,6 @@ static void test_namespaces_change(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMNamedNodeMap_get_length(map, &len); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!len, "Unexpected length %ld.\n", len); IXMLDOMNamedNodeMap_Release(map); @@ -8316,8 +8313,7 @@ static void test_setAttributeNode(void) hr = IXMLDOMElement_get_xml(elem, &str); ok( hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(lstrcmpW(str, L"<test attr=\"attrvalue2\"/>") == 0, - "got %s\n", wine_dbgstr_w(str)); + ok(!lstrcmpW(str, L"<test attr=\"attrvalue2\"/>"), "got %s\n", wine_dbgstr_w(str)); SysFreeString(str); IXMLDOMElement_Release(elem); @@ -8780,7 +8776,6 @@ static void test_createProcessingInstruction(void) hr = IXMLDOMDocument_get_xml(doc, &xml); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(xml, xml1), "got %s\n", wine_dbgstr_w(xml)); SysFreeString(xml); @@ -8794,7 +8789,6 @@ static void test_createProcessingInstruction(void) hr = GetHGlobalFromStream(stream, &global); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); p = GlobalLock(global); - todo_wine ok(!memcmp(p, xml2, sizeof(xml2) - 1), "Unexpected output %s.\n", wine_dbgstr_a(p)); GlobalUnlock(global); @@ -8817,7 +8811,6 @@ static void test_createProcessingInstruction(void) hr = GetHGlobalFromStream(stream, &global); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); p = GlobalLock(global); - todo_wine ok(!memcmp(p, xml2, sizeof(xml2) - 1), "Unexpected output %s.\n", wine_dbgstr_a(p)); GlobalUnlock(global); @@ -8839,7 +8832,6 @@ static void test_createProcessingInstruction(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); p = GlobalLock(global); - todo_wine ok(!memcmp(p, xml3, sizeof(xml3) - 1), "Unexpected output %s.\n", wine_dbgstr_a(p)); GlobalUnlock(global); @@ -9168,7 +9160,6 @@ static void test_get_xml(void) hr = IXMLDOMDocument_get_xml(doc, &xml); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(xml, L"<a xmlns:ns=\"uri\"><b ns:attr=\"value\" xmlns:ns=\"uri\"/></a>\r\n"), "Unexpected xml %s.\n", wine_dbgstr_w(xml)); SysFreeString(xml); @@ -9179,7 +9170,6 @@ static void test_get_xml(void) hr = IXMLDOMDocument_get_xml(doc, &xml); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(xml, L"<a><elem xmlns=\"http://blah.org\"/></a>\r\n"), "Unexpected xml %s.\n", wine_dbgstr_w(xml)); SysFreeString(xml); @@ -9793,7 +9783,7 @@ static void test_insertBefore(void) p = NULL; hr = IXMLDOMElement_get_xml(elem1, &p); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(p, L"<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>"), + ok(!lstrcmpW(p, L"<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>"), "got %s\n", wine_dbgstr_w(p)); SysFreeString(p); @@ -9913,7 +9903,6 @@ static void test_appendChild(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode *)elem2, NULL); - todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMDocument_createComment(doc, _bstr_("Comment1"), &comment1); @@ -9966,7 +9955,6 @@ static void test_appendChild(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(node == (IXMLDOMNode *)fragment, "Unexpected child %p.\n", node); IXMLDOMNode_Release(node); - todo_wine EXPECT_NO_CHILDREN(fragment); hr = IXMLDOMElement_get_childNodes(elem, &list); @@ -9974,13 +9962,11 @@ static void test_appendChild(void) hr = IXMLDOMNodeList_get_length(list, &length); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(length == 2, "Unexpected length %ld.\n", length); while (IXMLDOMNodeList_nextNode(list, &node) == S_OK) { hr = IXMLDOMNode_get_nodeType(node, &node_type); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(node_type == NODE_TEXT, "Unexpected type %d.\n", node_type); IXMLDOMNode_Release(node); } @@ -10032,24 +10018,18 @@ static void test_get_doctype(void) SysFreeString(s); hr = IXMLDOMDocumentType_get_nodeValue(doctype, NULL); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); V_VT(&v) = VT_EMPTY; hr = IXMLDOMDocumentType_get_nodeValue(doctype, &v); - todo_wine ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr); - todo_wine ok(V_VT(&v) == VT_NULL, "Unexpected type %d.\n", V_VT(&v)); hr = IXMLDOMDocumentType_get_text(doctype, NULL); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMDocumentType_get_text(doctype, &s); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!*s, "Unexpected text %s\n", wine_dbgstr_w(s)); SysFreeString(s); @@ -10060,9 +10040,7 @@ static void test_get_doctype(void) /* The 'xml' property contains original doctype text as-is, with newlines normalized */ hr = IXMLDOMDocumentType_get_xml(doctype, &s); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(s, _bstr_(SZ_EMAIL_DTD)), "Unexpected text %s\n", wine_dbgstr_w(s)); SysFreeString(s); @@ -10296,7 +10274,7 @@ static void test_get_attributes(void) length = -1; hr = IXMLDOMNamedNodeMap_get_length(map, &length); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(length == 1, "got %ld\n", length); + ok(length == 1, "got %ld\n", length); if (hr == S_OK && length == 1) { @@ -10367,10 +10345,8 @@ static void test_get_attributes(void) hr = IXMLDOMAttribute_put_nodeValue(attr, _variantbstr_("UTF-8")); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - EXPECT_REF(attr, 2); hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - EXPECT_REF(attr, 2); hr = IXMLDOMNode_get_attributes(node, &map); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -11153,7 +11129,9 @@ static void test_load(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMDocument_load(doc, src, &b); + todo_wine ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr); + todo_wine ok(b == VARIANT_FALSE, "got %d\n", b); VariantClear(&src); @@ -12496,12 +12474,9 @@ static void test_supporterrorinfo(void) refcount = get_refcount(doctype); hr = IXMLDOMDocumentType_QueryInterface(doctype, &IID_ISupportErrorInfo, (void **)&errorinfo); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(refcount == get_refcount(doctype), "Unexpected refcount %ld.\n", refcount); -if (hr == S_OK) -{ check_interface(errorinfo, &IID_IXMLDOMNode, FALSE); hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMNode); @@ -12511,7 +12486,7 @@ if (hr == S_OK) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ISupportErrorInfo_Release(errorinfo); -} + IXMLDOMDocumentType_Release(doctype); IXMLDOMDocument_Release(doc); @@ -12619,7 +12594,7 @@ static void test_xmlns_attribute(void) str = NULL; hr = IXMLDOMElement_get_xml(elem, &str); ok( hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(lstrcmpW(str, L"<Testing xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"bin.base64\"/>") == 0, + ok(!lstrcmpW(str, L"<Testing xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"bin.base64\"/>"), "got %s\n", wine_dbgstr_w(str)); SysFreeString(str); @@ -14357,9 +14332,6 @@ static void test_put_text(void) const WCHAR *expected; HRESULT hr; - if (winetest_platform_is_wine) /* put_text causes ASan errors and crash in Release */ - return; - doc = create_document(&IID_IXMLDOMDocument2); b = VARIANT_FALSE; @@ -14428,7 +14400,6 @@ static void test_put_text(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); expected = L"<open what=\"window\">sesame</open>"; - todo_wine ok(!lstrcmpW(str, expected), "Incorrect element string, got '%s'\n", wine_dbgstr_w(str)); SysFreeString(str); @@ -14620,9 +14591,6 @@ static void test_removeAttributeNode(void) HRESULT hr; BSTR str; - if (winetest_platform_is_wine) - return; - hr = CoCreateInstance(&CLSID_DOMDocument30, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void **)&doc); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -14634,7 +14602,6 @@ static void test_removeAttributeNode(void) hr = IXMLDOMElement_get_xml(element, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"<a ns:attr1=\"attr1-value\" xmlns:ns=\"uri\"><ns:b ns:attr=\"attr-value\"/></a>"), "Unexpected str %s.\n", debugstr_w(str)); SysFreeString(str); @@ -14651,17 +14618,14 @@ static void test_removeAttributeNode(void) /* Try to remove namespace definition that's in use */ hr = IXMLDOMElement_removeAttribute(element, _bstr_("xmlns:ns")); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMElement_get_xml(element, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"<a xmlns:ns=\"uri\" ns:attr1=\"attr1-value\"><ns:b ns:attr=\"attr-value\"/></a>"), "Unexpected str %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMElement_getAttribute(element, _bstr_("xmlns:ns"), &var); - todo_wine ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMElement_getAttributeNode(element, _bstr_("attr1"), &attr); @@ -14681,7 +14645,6 @@ static void test_removeAttributeNode(void) hr = IXMLDOMElement_get_xml(element, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"<a><ns:b xmlns:ns=\"uri\" ns:attr=\"attr-value\"/></a>"), "Unexpected str %s.\n", debugstr_w(str)); SysFreeString(str); @@ -14695,26 +14658,20 @@ static void test_removeAttributeNode(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMElement_getAttributeNode(element, _bstr_("xmlns:ns"), &attr); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - hr = IXMLDOMAttribute_put_text(attr, _bstr_("uri-2")); - ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); + hr = IXMLDOMAttribute_put_text(attr, _bstr_("uri-2")); + ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); - IXMLDOMAttribute_Release(attr); - } + IXMLDOMAttribute_Release(attr); hr = IXMLDOMElement_getAttributeNode(element, _bstr_("ns:attr1"), &attr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMElement_setAttribute(element, _bstr_("xmlns:ns"), _variantbstr_("uri2")); - todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMElement_setAttribute(element, _bstr_("xmlns:ns"), _variantbstr_("uri")); - todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMAttribute_get_namespaceURI(attr, &str); @@ -14726,7 +14683,6 @@ static void test_removeAttributeNode(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMElement_setAttribute(element, _bstr_("xmlns:ns"), _variantbstr_("uri2")); - todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMAttribute_get_namespaceURI(attr, &str); @@ -14760,7 +14716,6 @@ static void test_comment(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMDocument_createComment(doc, _bstr_("A Comment -->"), &comment); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr ); hr = IXMLDOMDocument_createComment(doc, _bstr_("A \nCo\rmment\r\n & < \""), &comment); @@ -14773,30 +14728,25 @@ static void test_comment(void) hr = IXMLDOMComment_get_xml(comment, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW(str, L"<!--A \r\nCo\r\nmment\r\n & < \"-->"), "Unexpected xml %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMComment_get_text(comment, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW(str, L"A \nCo\nmment\n & < \""), "Unexpected text %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMComment_get_data(comment, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW(str, L"A \nCo\nmment\n & < \""), "Unexpected text %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMComment_get_nodeValue(comment, &v); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW(str, L"A \nCo\nmment\n & < \""), "Unexpected text %s.\n", debugstr_w(str)); VariantClear(&v); hr = IXMLDOMComment_put_nodeValue(comment, _variantbstr_("comment --> a")); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr ); hr = IXMLDOMComment_put_nodeValue(comment, _variantbstr_("comment \ra")); @@ -14804,13 +14754,11 @@ static void test_comment(void) hr = IXMLDOMComment_get_data(comment, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW(str, L"comment \na"), "Unexpected text %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMComment_get_nodeValue(comment, &v); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW(V_BSTR(&v), L"comment \na"), "Unexpected text %s.\n", debugstr_w(V_BSTR(&v))); VariantClear(&v); @@ -14819,7 +14767,6 @@ static void test_comment(void) hr = IXMLDOMComment_get_xml(comment, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW( str, L"<!--comment \r\na-->" ), "Unexpected xml %s.\n", debugstr_w(str)); SysFreeString(str); @@ -15135,7 +15082,6 @@ static void test_pi(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("target"), _bstr_("Some text ?>"), &pi); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr ); hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("target"), _bstr_("A \nCo\rmment\r\n & < \""), &pi); @@ -15148,30 +15094,25 @@ static void test_pi(void) hr = IXMLDOMProcessingInstruction_get_xml(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW(str, L"<?target A \r\nCo\r\nmment\r\n & < \"?>"), "Unexpected xml %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMProcessingInstruction_get_text(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW(str, L"A \nCo\nmment\n & < \""), "Unexpected text %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMProcessingInstruction_get_data(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW(str, L"A \nCo\nmment\n & < \""), "Unexpected text %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMProcessingInstruction_get_nodeValue(pi, &v); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW(str, L"A \nCo\nmment\n & < \""), "Unexpected text %s.\n", debugstr_w(str)); VariantClear(&v); hr = IXMLDOMProcessingInstruction_put_nodeValue(pi, _variantbstr_("comment ?> a")); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr ); hr = IXMLDOMProcessingInstruction_put_nodeValue(pi, _variantbstr_("comment \na")); @@ -15179,7 +15120,6 @@ static void test_pi(void) hr = IXMLDOMProcessingInstruction_get_xml(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr ); - todo_wine ok(!lstrcmpW( str, L"<?target comment \r\na?>"), "Unexpected xml %s.\n", debugstr_w(str)); SysFreeString(str); @@ -15230,15 +15170,12 @@ static void test_pi(void) /* Can't have markup */ hr = IXMLDOMProcessingInstruction_put_data(pi, _bstr_("da?>ta")); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMProcessingInstruction_put_text(pi, _bstr_("da?>ta")); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMProcessingInstruction_put_nodeValue(pi, _variantbstr_("da?>ta")); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); VariantClear(&v); @@ -15393,7 +15330,6 @@ static void test_doc_fragment(void) hr = IXMLDOMDocumentFragment_get_xml(fragment, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(str, L"<?t pi-text?>"), "Unexpected xml %s.\n", debugstr_w(str)); SysFreeString(str); @@ -15411,7 +15347,6 @@ static void test_doc_fragment(void) hr = IXMLDOMDocumentFragment_get_xml(fragment, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(str, L"<?t pi-text?>text-node"), "Unexpected xml %s.\n", debugstr_w(str)); SysFreeString(str); @@ -15429,7 +15364,6 @@ static void test_doc_fragment(void) hr = IXMLDOMDocumentFragment_get_xml(fragment, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(str, L"<?t pi-text?>text-node<!--comment-->"), "Unexpected xml %s.\n", debugstr_w(str)); SysFreeString(str); @@ -15447,7 +15381,6 @@ static void test_doc_fragment(void) hr = IXMLDOMDocumentFragment_get_xml(fragment, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(str, L"<?t pi-text?>text-node<!--comment--><![CDATA[cdata]]>"), "Unexpected xml %s.\n", debugstr_w(str)); SysFreeString(str); @@ -15470,7 +15403,6 @@ static void test_doc_fragment(void) hr = IXMLDOMDocumentFragment_get_xml(fragment, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(str, L"<?t pi-text?>text-node<!--comment--><![CDATA[cdata]]><e2>text-node2</e2>"), "Unexpected xml %s.\n", debugstr_w(str)); SysFreeString(str); @@ -15488,7 +15420,6 @@ static void test_doc_fragment(void) hr = IXMLDOMDocumentFragment_get_xml(fragment, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(str, L"<?t pi-text?>text-node<!--comment--><![CDATA[cdata]]>" "<e2>text-node2<!--comment2--></e2>"), "Unexpected xml %s.\n", debugstr_w(str)); @@ -15581,19 +15512,16 @@ static void test_text(void) hr = IXMLDOMText_get_data(nodetext, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(str, L"t\ne\nx\nt"), "Unexpected data %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMText_get_text(nodetext, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(str, L"t\ne\nx\nt"), "Unexpected data %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMText_get_nodeValue(nodetext, &var); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(V_BSTR(&var), L"t\ne\nx\nt"), "Unexpected data %s.\n", debugstr_w(V_BSTR(&var))); VariantClear(&var); @@ -15602,19 +15530,16 @@ static void test_text(void) hr = IXMLDOMText_get_data(nodetext, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(str, L"t\ne\nx\nt"), "Unexpected data %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMText_get_text(nodetext, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(str, L"t\ne\nx\nt"), "Unexpected data %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMText_get_nodeValue(nodetext, &var); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!lstrcmpW(V_BSTR(&var), L"t\ne\nx\nt"), "Unexpected data %s.\n", debugstr_w(V_BSTR(&var))); VariantClear(&var); @@ -16026,9 +15951,7 @@ static void test_attribute_value(void) b = VARIANT_FALSE; hr = IXMLDOMAttribute_hasChildNodes(attr, &b); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(b == VARIANT_TRUE, "Unexpected value %d.\n", b); V_VT(&value) = VT_EMPTY; @@ -16037,9 +15960,7 @@ static void test_attribute_value(void) b = VARIANT_FALSE; hr = IXMLDOMAttribute_hasChildNodes(attr, &b); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(b == VARIANT_TRUE, "Unexpected value %d.\n", b); hr = IXMLDOMAttribute_put_value(attr, _variantbstr_("<>\"\'")); @@ -16098,46 +16019,36 @@ static void test_xmldecl_attributes(void) node = NULL; hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("encoding"), &node); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (node) - IXMLDOMNode_Release(node); + IXMLDOMNode_Release(node); hr = IXMLDOMProcessingInstruction_get_xml(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"<?xml version=\"1.0\" standalone=\"yes\"?>"), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); node = NULL; hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("standalone"), &node); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (node) - IXMLDOMNode_Release(node); + IXMLDOMNode_Release(node); hr = IXMLDOMProcessingInstruction_get_xml(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"<?xml version=\"1.0\"?>"), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMProcessingInstruction_get_data(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"version=\"1.0\""), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); node = NULL; hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), &node); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (node) - IXMLDOMNode_Release(node); + IXMLDOMNode_Release(node); hr = IXMLDOMProcessingInstruction_get_data(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L""), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); @@ -16147,7 +16058,6 @@ static void test_xmldecl_attributes(void) hr = IXMLDOMProcessingInstruction_get_xml(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"<?xml version=\"1.0\"?>"), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); @@ -16157,20 +16067,16 @@ static void test_xmldecl_attributes(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode *)attr, NULL); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - IXMLDOMAttribute_Release(attr); + IXMLDOMAttribute_Release(attr); hr = IXMLDOMProcessingInstruction_get_xml(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"<?xml version=\"1.0\" standalone=\"no\"?>"), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMProcessingInstruction_get_text(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"standalone=\"no\""), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); @@ -16180,46 +16086,36 @@ static void test_xmldecl_attributes(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode *)attr, NULL); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); IXMLDOMAttribute_Release(attr); hr = IXMLDOMNamedNodeMap_get_length(map, &length); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(length == 2, "Unexpected length %ld.\n", length); hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); -if (hr == S_OK) -{ hr = IXMLDOMNode_get_nodeName(node, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(!wcscmp(str, L"standalone"), "Unexpected name %s.\n", debugstr_w(str)); SysFreeString(str); IXMLDOMNode_Release(node); -} + hr = IXMLDOMNamedNodeMap_get_item(map, 1, &node); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); -if (hr == S_OK) -{ hr = IXMLDOMNode_get_nodeName(node, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(!wcscmp(str, L"encoding"), "Unexpected name %s.\n", debugstr_w(str)); SysFreeString(str); IXMLDOMNode_Release(node); -} + hr = IXMLDOMProcessingInstruction_get_text(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"standalone=\"no\" encoding=\"utf-8\""), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMProcessingInstruction_get_xml(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"<?xml version=\"1.0\" standalone=\"no\"?>"), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); @@ -16229,19 +16125,16 @@ if (hr == S_OK) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode *)attr, NULL); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); IXMLDOMAttribute_Release(attr); hr = IXMLDOMProcessingInstruction_get_text(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"standalone=\"no\" encoding=\"utf-8\" version=\"2.0abc\""), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); hr = IXMLDOMProcessingInstruction_get_xml(pi, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"<?xml version=\"2.0abc\" standalone=\"no\"?>"), "Unexpected string %s.\n", debugstr_w(str)); SysFreeString(str); @@ -16270,13 +16163,10 @@ static void test_loadXML(void) ok(b == VARIANT_FALSE, "Unexpected value %d.\n", b); hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a>text</a>"), NULL); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMDocument_get_documentElement(doc, &element); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - IXMLDOMElement_Release(element); + IXMLDOMElement_Release(element); /* Clears current document */ hr = IXMLDOMDocument_loadXML(doc, NULL, NULL); @@ -16699,13 +16589,11 @@ static void test_document_reload(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMDocument_get_xml(owner, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"<b>text</b>\r\n"), "Unexpected xml %s.\n", debugstr_w(str)); hr = IXMLDOMDocument_get_documentElement(owner, &element2); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IXMLDOMElement_get_xml(element2, &str); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(str, L"<b>text</b>"), "Unexpected xml %s.\n", debugstr_w(str)); SysFreeString(str); IXMLDOMElement_Release(element2); @@ -16722,7 +16610,6 @@ static void test_document_reload(void) hr = IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(!wcscmp(V_BSTR(&var), L"XSLPattern"), "Unexpected value %s.\n", debugstr_w(V_BSTR(&var))); VariantClear(&var); diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c index 353e48fabe1..b7a79bb8faa 100644 --- a/dlls/msxml3/tests/saxreader.c +++ b/dlls/msxml3/tests/saxreader.c @@ -3461,7 +3461,6 @@ static void test_saxreader_encoding(void) create_test_file(testXmlA, xml_win936_test, sizeof(xml_win936_test) - 1); hr = ISAXXMLReader_parseURL(reader, L"test.xml"); - todo_wine ok(FAILED(hr), "Unexpected hr %#lx.\n", hr); flush_sequence(sequences, CONTENT_HANDLER_INDEX); DeleteFileA(testXmlA); @@ -6450,7 +6449,6 @@ static void test_saxreader_parse_input(void) V_BSTR(&var) = SysAllocStringByteLen("<a>text</a>", 11); hr = ISAXXMLReader_parse(reader, var); - todo_wine ok(FAILED(hr), "Unexpected hr %#lx.\n", hr); VariantClear(&var); diff --git a/dlls/msxml3/tests/xmldoc.c b/dlls/msxml3/tests/xmldoc.c index 898b5f3c114..ce1e54a02cb 100644 --- a/dlls/msxml3/tests/xmldoc.c +++ b/dlls/msxml3/tests/xmldoc.c @@ -1280,7 +1280,6 @@ static void test_xmldoc_charset(void) /* Invalid encoding */ hr = load_document(doc, doc_data3, sizeof(doc_data3) - 1); - todo_wine ok(hr == XML_E_INVALIDENCODING, "Unexpected hr %#lx.\n", hr); IXMLDocument_Release(doc); diff --git a/dlls/msxml3/text.c b/dlls/msxml3/text.c index c2283760907..70edaf12367 100644 --- a/dlls/msxml3/text.c +++ b/dlls/msxml3/text.c @@ -22,9 +22,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/parserInternals.h> -#include <libxml/xmlerror.h> #include "windef.h" #include "winbase.h" @@ -40,9 +37,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); typedef struct _domtext { - xmlnode node; + DispatchEx dispex; IXMLDOMText IXMLDOMText_iface; - LONG ref; + LONG refcount; + struct domnode *node; } domtext; static inline domtext *impl_from_IXMLDOMText( IXMLDOMText *iface ) @@ -50,35 +48,32 @@ static inline domtext *impl_from_IXMLDOMText( IXMLDOMText *iface ) return CONTAINING_RECORD(iface, domtext, IXMLDOMText_iface); } -static void domtext_reset_noenc(domtext *This) +static HRESULT WINAPI domtext_QueryInterface(IXMLDOMText *iface, REFIID riid, void **obj) { - This->node.node->name = NULL; -} + domtext *text = impl_from_IXMLDOMText(iface); -static HRESULT WINAPI domtext_QueryInterface( - IXMLDOMText *iface, - REFIID riid, - void** ppvObject ) -{ - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); - if ( IsEqualGUID( riid, &IID_IXMLDOMText ) || - IsEqualGUID( riid, &IID_IXMLDOMCharacterData) || - IsEqualGUID( riid, &IID_IXMLDOMNode ) || - IsEqualGUID( riid, &IID_IDispatch ) || - IsEqualGUID( riid, &IID_IUnknown ) ) + if (IsEqualGUID(riid, &IID_IXMLDOMText) || + IsEqualGUID(riid, &IID_IXMLDOMCharacterData) || + IsEqualGUID(riid, &IID_IXMLDOMNode) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IUnknown) ) + { + *obj = iface; + } + else if (dispex_query_interface(&text->dispex, riid, obj)) { - *ppvObject = iface; + return *obj ? S_OK : E_NOINTERFACE; } - else if(node_query_interface(&This->node, riid, ppvObject)) + else if (node_query_interface(text->node, riid, obj)) { - return *ppvObject ? S_OK : E_NOINTERFACE; + return *obj ? S_OK : E_NOINTERFACE; } else { TRACE("Unsupported interface %s\n", debugstr_guid(riid)); - *ppvObject = NULL; + *obj = NULL; return E_NOINTERFACE; } @@ -86,57 +81,49 @@ static HRESULT WINAPI domtext_QueryInterface( return S_OK; } -static ULONG WINAPI domtext_AddRef( - IXMLDOMText *iface ) +static ULONG WINAPI domtext_AddRef(IXMLDOMText *iface) { - domtext *This = impl_from_IXMLDOMText( iface ); - ULONG ref = InterlockedIncrement( &This->ref ); - TRACE("%p, refcount %lu.\n", iface, ref); - return ref; + domtext *text = impl_from_IXMLDOMText(iface); + ULONG refcount = InterlockedIncrement(&text->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); + + return refcount; } -static ULONG WINAPI domtext_Release( - IXMLDOMText *iface ) +static ULONG WINAPI domtext_Release(IXMLDOMText *iface) { - domtext *This = impl_from_IXMLDOMText( iface ); - ULONG ref = InterlockedDecrement( &This->ref ); + domtext *text = impl_from_IXMLDOMText(iface); + ULONG refcount = InterlockedDecrement(&text->refcount); + + TRACE("%p, refcount %lu.\n", iface, refcount); - TRACE("%p, refcount %lu.\n", iface, ref); - if ( ref == 0 ) + if (!refcount) { - destroy_xmlnode(&This->node); - free(This); + domnode_release(text->node); + free(text); } - return ref; + return refcount; } -static HRESULT WINAPI domtext_GetTypeInfoCount( - IXMLDOMText *iface, - UINT* pctinfo ) +static HRESULT WINAPI domtext_GetTypeInfoCount(IXMLDOMText *iface, UINT *count) { - domtext *This = impl_from_IXMLDOMText( iface ); - return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); + domtext *text = impl_from_IXMLDOMText(iface); + return IDispatchEx_GetTypeInfoCount(&text->dispex.IDispatchEx_iface, count); } -static HRESULT WINAPI domtext_GetTypeInfo( - IXMLDOMText *iface, - UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo ) +static HRESULT WINAPI domtext_GetTypeInfo(IXMLDOMText *iface, UINT index, LCID lcid, ITypeInfo **ti) { - domtext *This = impl_from_IXMLDOMText( iface ); - return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, - iTInfo, lcid, ppTInfo); + domtext *text = impl_from_IXMLDOMText(iface); + return IDispatchEx_GetTypeInfo(&text->dispex.IDispatchEx_iface, index, lcid, ti); } -static HRESULT WINAPI domtext_GetIDsOfNames( - IXMLDOMText *iface, - REFIID riid, LPOLESTR* rgszNames, - UINT cNames, LCID lcid, DISPID* rgDispId ) +static HRESULT WINAPI domtext_GetIDsOfNames(IXMLDOMText *iface, REFIID riid, LPOLESTR *names, + UINT name_count, LCID lcid, DISPID *dispid) { - domtext *This = impl_from_IXMLDOMText( iface ); - return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, - riid, rgszNames, cNames, lcid, rgDispId); + domtext *text = impl_from_IXMLDOMText(iface); + return IDispatchEx_GetIDsOfNames(&text->dispex.IDispatchEx_iface, riid, names, name_count, lcid, dispid); } static HRESULT WINAPI domtext_Invoke( @@ -145,262 +132,210 @@ static HRESULT WINAPI domtext_Invoke( WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr ) { - domtext *This = impl_from_IXMLDOMText( iface ); - return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, + domtext *text = impl_from_IXMLDOMText(iface); + return IDispatchEx_Invoke(&text->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); } -static HRESULT WINAPI domtext_get_nodeName( - IXMLDOMText *iface, - BSTR* p ) +static HRESULT WINAPI domtext_get_nodeName(IXMLDOMText *iface, BSTR *p) { - domtext *This = impl_from_IXMLDOMText( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"#text", p); } -static HRESULT WINAPI domtext_get_nodeValue( - IXMLDOMText *iface, - VARIANT* value ) +static HRESULT WINAPI domtext_get_nodeValue(IXMLDOMText *iface, VARIANT *value) { - domtext *This = impl_from_IXMLDOMText( iface ); + domtext *text = impl_from_IXMLDOMText(iface); - TRACE("(%p)->(%p)\n", This, value); + TRACE("%p, %p.\n", iface, value); - return node_get_content(&This->node, value); + return node_get_value(text->node, value); } -static HRESULT WINAPI domtext_put_nodeValue( - IXMLDOMText *iface, - VARIANT value) +static HRESULT WINAPI domtext_put_nodeValue(IXMLDOMText *iface, VARIANT value) { - domtext *This = impl_from_IXMLDOMText( iface ); + domtext *text = impl_from_IXMLDOMText(iface); - TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + TRACE("%p, %s.\n", iface, debugstr_variant(&value)); - domtext_reset_noenc(This); - return node_put_value(&This->node, &value); + return node_put_value(text->node, &value); } -static HRESULT WINAPI domtext_get_nodeType( - IXMLDOMText *iface, - DOMNodeType* domNodeType ) +static HRESULT WINAPI domtext_get_nodeType(IXMLDOMText *iface, DOMNodeType *type) { - domtext *This = impl_from_IXMLDOMText( iface ); - - TRACE("(%p)->(%p)\n", This, domNodeType); + TRACE("%p, %p.\n", iface, type); - *domNodeType = NODE_TEXT; + *type = NODE_TEXT; return S_OK; } -static HRESULT WINAPI domtext_get_parentNode( - IXMLDOMText *iface, - IXMLDOMNode** parent ) +static HRESULT WINAPI domtext_get_parentNode(IXMLDOMText *iface, IXMLDOMNode **parent) { - domtext *This = impl_from_IXMLDOMText( iface ); + domtext *text = impl_from_IXMLDOMText(iface); - TRACE("(%p)->(%p)\n", This, parent); + TRACE("%p, %p.\n", iface, parent); - return node_get_parent(&This->node, parent); + return node_get_parent(text->node, parent); } -static HRESULT WINAPI domtext_get_childNodes( - IXMLDOMText *iface, - IXMLDOMNodeList** outList) +static HRESULT WINAPI domtext_get_childNodes(IXMLDOMText *iface, IXMLDOMNodeList **list) { - domtext *This = impl_from_IXMLDOMText( iface ); + domtext *text = impl_from_IXMLDOMText(iface); - TRACE("(%p)->(%p)\n", This, outList); + TRACE("%p, %p.\n", iface, list); - return node_get_child_nodes(&This->node, outList); + return node_get_child_nodes(text->node, list); } -static HRESULT WINAPI domtext_get_firstChild( - IXMLDOMText *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domtext_get_firstChild(IXMLDOMText *iface, IXMLDOMNode **node) { - domtext *This = impl_from_IXMLDOMText( iface ); + TRACE("%p, %p.\n", iface, node); - TRACE("(%p)->(%p)\n", This, domNode); - - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI domtext_get_lastChild( - IXMLDOMText *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domtext_get_lastChild(IXMLDOMText *iface, IXMLDOMNode **node) { - domtext *This = impl_from_IXMLDOMText( iface ); + TRACE("%p, %p.\n", iface, node); - TRACE("(%p)->(%p)\n", This, domNode); - - return return_null_node(domNode); + return return_null_node(node); } -static HRESULT WINAPI domtext_get_previousSibling( - IXMLDOMText *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domtext_get_previousSibling(IXMLDOMText *iface, IXMLDOMNode **node) { - domtext *This = impl_from_IXMLDOMText( iface ); + domtext *text = impl_from_IXMLDOMText(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_previous_sibling(&This->node, domNode); + return node_get_previous_sibling(text->node, node); } -static HRESULT WINAPI domtext_get_nextSibling( - IXMLDOMText *iface, - IXMLDOMNode** domNode) +static HRESULT WINAPI domtext_get_nextSibling(IXMLDOMText *iface, IXMLDOMNode **node) { - domtext *This = impl_from_IXMLDOMText( iface ); + domtext *text = impl_from_IXMLDOMText(iface); - TRACE("(%p)->(%p)\n", This, domNode); + TRACE("%p, %p.\n", iface, node); - return node_get_next_sibling(&This->node, domNode); + return node_get_next_sibling(text->node, node); } -static HRESULT WINAPI domtext_get_attributes( - IXMLDOMText *iface, - IXMLDOMNamedNodeMap** attributeMap) +static HRESULT WINAPI domtext_get_attributes(IXMLDOMText *iface, IXMLDOMNamedNodeMap **map) { - domtext *This = impl_from_IXMLDOMText( iface ); - - TRACE("(%p)->(%p)\n", This, attributeMap); + TRACE("%p, %p.\n", iface, map); - return return_null_ptr((void**)attributeMap); + return return_null_ptr((void **)map); } -static HRESULT WINAPI domtext_insertBefore( - IXMLDOMText *iface, - IXMLDOMNode* newNode, VARIANT refChild, +static HRESULT WINAPI domtext_insertBefore(IXMLDOMText *iface, IXMLDOMNode* newNode, VARIANT refChild, IXMLDOMNode** outOldNode) { - domtext *This = impl_from_IXMLDOMText( iface ); + domtext *text = impl_from_IXMLDOMText(iface); - FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode); + FIXME("%p, %p, %s, %p needs test\n", iface, newNode, debugstr_variant(&refChild), outOldNode); - return node_insert_before(&This->node, newNode, &refChild, outOldNode); + return node_insert_before(text->node, newNode, &refChild, outOldNode); } -static HRESULT WINAPI domtext_replaceChild( - IXMLDOMText *iface, - IXMLDOMNode* newNode, - IXMLDOMNode* oldNode, - IXMLDOMNode** outOldNode) +static HRESULT WINAPI domtext_replaceChild(IXMLDOMText *iface, IXMLDOMNode *newNode, + IXMLDOMNode *oldNode, IXMLDOMNode **outOldNode) { - domtext *This = impl_from_IXMLDOMText( iface ); + domtext *text = impl_from_IXMLDOMText(iface); - FIXME("(%p)->(%p %p %p) needs test\n", This, newNode, oldNode, outOldNode); + FIXME("%p, %p, %p, %p needs test\n", iface, newNode, oldNode, outOldNode); - return node_replace_child(&This->node, newNode, oldNode, outOldNode); + return node_replace_child(text->node, newNode, oldNode, outOldNode); } -static HRESULT WINAPI domtext_removeChild( - IXMLDOMText *iface, - IXMLDOMNode *child, IXMLDOMNode **oldChild) +static HRESULT WINAPI domtext_removeChild(IXMLDOMText *iface, IXMLDOMNode *child, IXMLDOMNode **oldChild) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%p %p)\n", This, child, oldChild); - return node_remove_child(&This->node, child, oldChild); + domtext *text = impl_from_IXMLDOMText(iface); + + TRACE("%p, %p, %p.\n", iface, child, oldChild); + + return node_remove_child(text->node, child, oldChild); } -static HRESULT WINAPI domtext_appendChild( - IXMLDOMText *iface, - IXMLDOMNode *child, IXMLDOMNode **outChild) +static HRESULT WINAPI domtext_appendChild(IXMLDOMText *iface, IXMLDOMNode *child, IXMLDOMNode **outChild) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%p %p)\n", This, child, outChild); - return node_append_child(&This->node, child, outChild); + domtext *text = impl_from_IXMLDOMText(iface); + + TRACE("%p, %p, %p.\n", iface, child, outChild); + + return node_append_child(text->node, child, outChild); } -static HRESULT WINAPI domtext_hasChildNodes( - IXMLDOMText *iface, - VARIANT_BOOL *ret) +static HRESULT WINAPI domtext_hasChildNodes(IXMLDOMText *iface, VARIANT_BOOL *v) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%p)\n", This, ret); - return return_var_false(ret); + TRACE("%p, %p.\n", iface, v); + + return return_var_false(v); } -static HRESULT WINAPI domtext_get_ownerDocument( - IXMLDOMText *iface, - IXMLDOMDocument **doc) +static HRESULT WINAPI domtext_get_ownerDocument(IXMLDOMText *iface, IXMLDOMDocument **doc) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%p)\n", This, doc); - return node_get_owner_doc(&This->node, doc); + domtext *text = impl_from_IXMLDOMText(iface); + + TRACE("%p, %p.\n", iface, doc); + + return node_get_owner_document(text->node, doc); } -static HRESULT WINAPI domtext_cloneNode( - IXMLDOMText *iface, - VARIANT_BOOL deep, IXMLDOMNode** outNode) +static HRESULT WINAPI domtext_cloneNode(IXMLDOMText *iface, VARIANT_BOOL deep, IXMLDOMNode **node) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%d %p)\n", This, deep, outNode); - return node_clone( &This->node, deep, outNode ); + domtext *text = impl_from_IXMLDOMText(iface); + + TRACE("%p, %d, %p.\n", iface, deep, node); + + return node_clone(text->node, deep, node); } -static HRESULT WINAPI domtext_get_nodeTypeString( - IXMLDOMText *iface, - BSTR* p) +static HRESULT WINAPI domtext_get_nodeTypeString(IXMLDOMText *iface, BSTR *p) { - domtext *This = impl_from_IXMLDOMText( iface ); - - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); return return_bstr(L"text", p); } -static HRESULT WINAPI domtext_get_text( - IXMLDOMText *iface, - BSTR* p) +static HRESULT WINAPI domtext_get_text(IXMLDOMText *iface, BSTR *p) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_text(&This->node, p); + domtext *text = impl_from_IXMLDOMText(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_text(text->node, p); } -static HRESULT WINAPI domtext_put_text( - IXMLDOMText *iface, - BSTR p) +static HRESULT WINAPI domtext_put_text(IXMLDOMText *iface, BSTR p) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - domtext_reset_noenc(This); - return node_put_text( &This->node, p ); + domtext *text = impl_from_IXMLDOMText(iface); + + TRACE("%p, %s.\n", iface, debugstr_w(p)); + + return node_put_data(text->node, p); } -static HRESULT WINAPI domtext_get_specified( - IXMLDOMText *iface, - VARIANT_BOOL* isSpecified) +static HRESULT WINAPI domtext_get_specified(IXMLDOMText *iface, VARIANT_BOOL *v) { - domtext *This = impl_from_IXMLDOMText( iface ); - FIXME("(%p)->(%p) stub!\n", This, isSpecified); - *isSpecified = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domtext_get_definition( - IXMLDOMText *iface, - IXMLDOMNode** definitionNode) +static HRESULT WINAPI domtext_get_definition(IXMLDOMText *iface, IXMLDOMNode **node) { - domtext *This = impl_from_IXMLDOMText( iface ); - FIXME("(%p)->(%p)\n", This, definitionNode); + FIXME("%p, %p.\n", iface, node); + return E_NOTIMPL; } -static HRESULT WINAPI domtext_get_nodeTypedValue( - IXMLDOMText *iface, - VARIANT* var1) +static HRESULT WINAPI domtext_get_nodeTypedValue(IXMLDOMText *iface, VARIANT *var1) { - domtext *This = impl_from_IXMLDOMText( iface ); IXMLDOMNode* parent = NULL; HRESULT hr; - TRACE("(%p)->(%p)\n", This, var1); + TRACE("%p, %p.\n", iface, var1); if (!var1) return E_INVALIDARG; @@ -477,15 +412,12 @@ static HRESULT WINAPI domtext_get_dataType( return hr; } -static HRESULT WINAPI domtext_put_dataType( - IXMLDOMText *iface, - BSTR dtName) +static HRESULT WINAPI domtext_put_dataType(IXMLDOMText *iface, BSTR dtName) { - domtext *This = impl_from_IXMLDOMText( iface ); IXMLDOMNode* parent = NULL; HRESULT hr; - TRACE("(%p)->(%p)\n", This, dtName); + TRACE("%p, %s.\n", iface, debugstr_w(dtName)); if (!dtName) return E_INVALIDARG; @@ -505,160 +437,110 @@ static HRESULT WINAPI domtext_put_dataType( return hr; } -static HRESULT WINAPI domtext_get_xml( - IXMLDOMText *iface, - BSTR* p) +static HRESULT WINAPI domtext_get_xml(IXMLDOMText *iface, BSTR *p) { - domtext *This = impl_from_IXMLDOMText( iface ); + domtext *text = impl_from_IXMLDOMText(iface); - TRACE("(%p)->(%p)\n", This, p); + TRACE("%p, %p.\n", iface, p); - return node_get_xml(&This->node, TRUE, p); + return node_get_xml(text->node, p); } -static HRESULT WINAPI domtext_transformNode( - IXMLDOMText *iface, - IXMLDOMNode *node, BSTR *p) +static HRESULT WINAPI domtext_transformNode(IXMLDOMText *iface, IXMLDOMNode *node, BSTR *p) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%p %p)\n", This, node, p); - return node_transform_node(&This->node, node, p); + domtext *text = impl_from_IXMLDOMText(iface); + + TRACE("%p, %p, %p.\n", iface, node, p); + + return node_transform_node(text->node, node, p); } -static HRESULT WINAPI domtext_selectNodes( - IXMLDOMText *iface, - BSTR p, IXMLDOMNodeList** outList) +static HRESULT WINAPI domtext_selectNodes(IXMLDOMText *iface, BSTR p, IXMLDOMNodeList **list) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); - return node_select_nodes(&This->node, p, outList); + domtext *text = impl_from_IXMLDOMText(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), list); + + return node_select_nodes(text->node, p, list); } -static HRESULT WINAPI domtext_selectSingleNode( - IXMLDOMText *iface, - BSTR p, IXMLDOMNode** outNode) +static HRESULT WINAPI domtext_selectSingleNode(IXMLDOMText *iface, BSTR p, IXMLDOMNode **node) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); - return node_select_singlenode(&This->node, p, outNode); + domtext *text = impl_from_IXMLDOMText(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_w(p), node); + + return node_select_singlenode(text->node, p, node); } -static HRESULT WINAPI domtext_get_parsed( - IXMLDOMText *iface, - VARIANT_BOOL* isParsed) +static HRESULT WINAPI domtext_get_parsed(IXMLDOMText *iface, VARIANT_BOOL *v) { - domtext *This = impl_from_IXMLDOMText( iface ); - FIXME("(%p)->(%p) stub!\n", This, isParsed); - *isParsed = VARIANT_TRUE; + FIXME("%p, %p stub!\n", iface, v); + + *v = VARIANT_TRUE; return S_OK; } -static HRESULT WINAPI domtext_get_namespaceURI( - IXMLDOMText *iface, - BSTR* p) +static HRESULT WINAPI domtext_get_namespaceURI(IXMLDOMText *iface, BSTR *p) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%p)\n", This, p); - return node_get_namespaceURI(&This->node, p); + domtext *text = impl_from_IXMLDOMText(iface); + + TRACE("%p, %p.\n", iface, p); + + return node_get_namespaceURI(text->node, p); } -static HRESULT WINAPI domtext_get_prefix( - IXMLDOMText *iface, - BSTR* prefix) +static HRESULT WINAPI domtext_get_prefix(IXMLDOMText *iface, BSTR *p) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%p)\n", This, prefix); - return return_null_bstr( prefix ); + TRACE("%p, %p.\n", iface, p); + + return return_null_bstr(p); } -static HRESULT WINAPI domtext_get_baseName( - IXMLDOMText *iface, - BSTR* name) +static HRESULT WINAPI domtext_get_baseName(IXMLDOMText *iface, BSTR *name) { - domtext *This = impl_from_IXMLDOMText( iface ); - TRACE("(%p)->(%p)\n", This, name); - return return_null_bstr( name ); + TRACE("%p, %p.\n", iface, name); + + return return_null_bstr(name); } -static HRESULT WINAPI domtext_transformNodeToObject( - IXMLDOMText *iface, - IXMLDOMNode* domNode, VARIANT var1) +static HRESULT WINAPI domtext_transformNodeToObject(IXMLDOMText *iface, IXMLDOMNode *node, VARIANT v) { - domtext *This = impl_from_IXMLDOMText( iface ); - FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); + FIXME("%p, %p, %s.\n", iface, node, debugstr_variant(&v)); + return E_NOTIMPL; } -static HRESULT WINAPI domtext_get_data( - IXMLDOMText *iface, - BSTR *p) +static HRESULT WINAPI domtext_get_data(IXMLDOMText *iface, BSTR *p) { - domtext *This = impl_from_IXMLDOMText( iface ); + domtext *text = impl_from_IXMLDOMText( iface ); - if(!p) - return E_INVALIDARG; + TRACE("%p, %p.\n", iface, p); - *p = bstr_from_xmlChar(This->node.node->content); - return S_OK; + return node_get_data(text->node, p); } -static HRESULT WINAPI domtext_put_data( - IXMLDOMText *iface, - BSTR data) +static HRESULT WINAPI domtext_put_data(IXMLDOMText *iface, BSTR data) { - domtext *This = impl_from_IXMLDOMText( iface ); - BSTR normalized_data = NULL; - HRESULT hr; - size_t i, j; + domtext *text = impl_from_IXMLDOMText(iface); - TRACE("(%p)->(%s)\n", This, debugstr_w(data)); + TRACE("%p, %s.\n", iface, debugstr_w(data)); - if (data) - { - /* normalize line endings */ - normalized_data = SysAllocStringLen(NULL, SysStringLen(data)); - if (!normalized_data) return E_OUTOFMEMORY; - for (i = 0, j = 0; data[i]; i++) - { - if (data[i] == '\r') - { - if (data[i + 1] == '\n') i++; /* change \r\n to just \n */ - normalized_data[j++] = '\n'; /* change \r by itself to \n */ - } - else - normalized_data[j++] = data[i]; - } - normalized_data[j] = 0; - } - - domtext_reset_noenc(This); - hr = node_set_content(&This->node, normalized_data); - - SysFreeString(normalized_data); - return hr; + return node_put_data(text->node, data); } -static HRESULT WINAPI domtext_get_length( - IXMLDOMText *iface, - LONG *len) +static HRESULT WINAPI domtext_get_length(IXMLDOMText *iface, LONG *len) { - domtext *This = impl_from_IXMLDOMText( iface ); - HRESULT hr; - BSTR data; + domtext *text = impl_from_IXMLDOMText(iface); - TRACE("(%p)->(%p)\n", This, len); + TRACE("%p, %p.\n", iface, len); - if(!len) + if (!len) return E_INVALIDARG; - hr = IXMLDOMText_get_data(iface, &data); - if(hr == S_OK) - { - *len = SysStringLen(data); - SysFreeString(data); - } + *len = SysStringLen(text->node->data); - return hr; + return S_OK; } static HRESULT WINAPI domtext_substringData( @@ -701,37 +583,13 @@ static HRESULT WINAPI domtext_substringData( return hr; } -static HRESULT WINAPI domtext_appendData( - IXMLDOMText *iface, - BSTR p) +static HRESULT WINAPI domtext_appendData(IXMLDOMText *iface, BSTR p) { - domtext *This = impl_from_IXMLDOMText( iface ); - HRESULT hr; - BSTR data; - LONG p_len; - - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - - /* Nothing to do if NULL or an Empty string passed in. */ - if((p_len = SysStringLen(p)) == 0) return S_OK; + domtext *text = impl_from_IXMLDOMText(iface); - hr = IXMLDOMText_get_data(iface, &data); - if(hr == S_OK) - { - LONG len = SysStringLen(data); - BSTR str = SysAllocStringLen(NULL, p_len + len); - - memcpy(str, data, len*sizeof(WCHAR)); - memcpy(&str[len], p, p_len*sizeof(WCHAR)); - str[len+p_len] = 0; - - hr = IXMLDOMText_put_data(iface, str); + TRACE("%p, %s.\n", iface, debugstr_w(p)); - SysFreeString(str); - SysFreeString(data); - } - - return hr; + return node_append_data(text->node, p); } static HRESULT WINAPI domtext_insertData( @@ -922,30 +780,36 @@ static const struct IXMLDOMTextVtbl domtext_vtbl = domtext_splitText }; -static const tid_t domtext_iface_tids[] = { +static const tid_t domtext_iface_tids[] = +{ IXMLDOMText_tid, 0 }; -static dispex_static_data_t domtext_dispex = { +static dispex_static_data_t domtext_dispex = +{ NULL, IXMLDOMText_tid, NULL, domtext_iface_tids }; -IUnknown* create_text( xmlNodePtr text ) +HRESULT create_text(struct domnode *node, IUnknown **obj) { - domtext *This; + domtext *object; + + *obj = NULL; - This = malloc(sizeof(*This)); - if ( !This ) - return NULL; + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; - This->IXMLDOMText_iface.lpVtbl = &domtext_vtbl; - This->ref = 1; + object->IXMLDOMText_iface.lpVtbl = &domtext_vtbl; + object->refcount = 1; + object->node = domnode_addref(node); - init_xmlnode(&This->node, text, (IXMLDOMNode*)&This->IXMLDOMText_iface, &domtext_dispex); + init_dispex(&object->dispex, (IUnknown *)&object->IXMLDOMText_iface, &domtext_dispex); - return (IUnknown*)&This->IXMLDOMText_iface; + *obj = (IUnknown *)&object->IXMLDOMText_iface; + + return S_OK; } diff --git a/dlls/msxml3/xmldoc.c b/dlls/msxml3/xmldoc.c index 125d041c8f8..be37226242f 100644 --- a/dlls/msxml3/xmldoc.c +++ b/dlls/msxml3/xmldoc.c @@ -22,7 +22,6 @@ #define COBJMACROS #include <stdarg.h> -#include <libxml/parser.h> #include "windef.h" #include "winbase.h" @@ -215,7 +214,7 @@ static HRESULT _node_append_attribute(struct node *node, const WCHAR *name, int return S_OK; } -static HRESULT node_set_attribute_value(struct node *node, const WCHAR *name, const VARIANT *value) +static HRESULT _node_set_attribute_value(struct node *node, const WCHAR *name, const VARIANT *value) { struct attribute *attr; @@ -230,7 +229,7 @@ static HRESULT node_set_attribute_value(struct node *node, const WCHAR *name, co } /* TODO: add a test for xml:lang */ -static HRESULT node_get_attribute_value(struct node *node, const WCHAR *name, VARIANT *value) +static HRESULT _node_get_attribute_value(struct node *node, const WCHAR *name, VARIANT *value) { struct attribute *attr; @@ -888,7 +887,7 @@ static HRESULT WINAPI xmlelem_setAttribute(IXMLElement2 *iface, BSTR name, VARIA TRACE("%p, %s, %s.\n", iface, debugstr_w(name), debugstr_variant(&value)); - return node_set_attribute_value(element->node, name, &value); + return _node_set_attribute_value(element->node, name, &value); } static HRESULT WINAPI xmlelem_getAttribute(IXMLElement2 *iface, BSTR name, @@ -898,7 +897,7 @@ static HRESULT WINAPI xmlelem_getAttribute(IXMLElement2 *iface, BSTR name, TRACE("%p, %s, %p.\n", iface, debugstr_w(name), value); - return node_get_attribute_value(element->node, name, value); + return _node_get_attribute_value(element->node, name, value); } static HRESULT WINAPI xmlelem_removeAttribute(IXMLElement2 *iface, BSTR name) diff --git a/dlls/msxml4/tests/saxreader.c b/dlls/msxml4/tests/saxreader.c index 0749146a5c6..196208c8d75 100644 --- a/dlls/msxml4/tests/saxreader.c +++ b/dlls/msxml4/tests/saxreader.c @@ -2679,11 +2679,8 @@ static void test_saxreader_properties(void) V_VT(&v) = VT_EMPTY; V_BSTR(&v) = (void*)0xdeadbeef; hr = ISAXXMLReader_getProperty(reader, L"xmldecl-encoding", &v); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); - todo_wine ok(!V_BSTR(&v), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); V_VT(&v) = VT_EMPTY; @@ -2726,14 +2723,10 @@ static void test_saxreader_properties(void) V_VT(&v) = VT_EMPTY; V_BSTR(&v) = (void*)0xdeadbeef; hr = ISAXXMLReader_getProperty(reader, L"xmldecl-encoding", &v); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); - ok(!wcscmp(V_BSTR(&v), L"uTf-16"), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); - VariantClear(&v); - } + ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); + ok(!wcscmp(V_BSTR(&v), L"uTf-16"), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); V_VT(&v) = VT_EMPTY; V_BSTR(&v) = (void*)0xdeadbeef; diff --git a/dlls/msxml6/tests/saxreader.c b/dlls/msxml6/tests/saxreader.c index 847d71ac149..1f10ad9b929 100644 --- a/dlls/msxml6/tests/saxreader.c +++ b/dlls/msxml6/tests/saxreader.c @@ -4955,11 +4955,8 @@ static void test_saxreader_properties(void) V_VT(&v) = VT_EMPTY; V_BSTR(&v) = (void*)0xdeadbeef; hr = ISAXXMLReader_getProperty(reader, L"xmldecl-encoding", &v); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); - todo_wine ok(!V_BSTR(&v), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); /* stream with declaration */ @@ -4992,14 +4989,10 @@ static void test_saxreader_properties(void) V_VT(&v) = VT_EMPTY; V_BSTR(&v) = (void*)0xdeadbeef; hr = ISAXXMLReader_getProperty(reader, L"xmldecl-encoding", &v); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); - ok(!wcscmp(V_BSTR(&v), L"uTf-16"), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); - VariantClear(&v); - } + ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); + ok(!wcscmp(V_BSTR(&v), L"uTf-16"), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); ISAXXMLReader_Release(reader); free_bstrs(); diff --git a/libs/xml2/include/libxml/tree.h b/libs/xml2/include/libxml/tree.h index 61c1ed49d95..574347da4c0 100644 --- a/libs/xml2/include/libxml/tree.h +++ b/libs/xml2/include/libxml/tree.h @@ -265,6 +265,7 @@ typedef struct _xmlAttribute xmlAttribute; typedef xmlAttribute *xmlAttributePtr; struct _xmlAttribute { void *_private; /* application data */ + void *_private2; xmlElementType type; /* XML_ATTRIBUTE_DECL, must be second ! */ const xmlChar *name; /* Attribute name */ struct _xmlNode *children; /* NULL */ @@ -350,6 +351,7 @@ typedef struct _xmlElement xmlElement; typedef xmlElement *xmlElementPtr; struct _xmlElement { void *_private; /* application data */ + void *_private2; xmlElementType type; /* XML_ELEMENT_DECL, must be second ! */ const xmlChar *name; /* Element name */ struct _xmlNode *children; /* NULL */ @@ -393,6 +395,7 @@ typedef struct _xmlNs xmlNs; typedef xmlNs *xmlNsPtr; struct _xmlNs { struct _xmlNs *next; /* next Ns link for this node */ + void *_pad; xmlNsType type; /* global or local */ const xmlChar *href; /* URL for the namespace */ const xmlChar *prefix; /* prefix for the namespace */ @@ -410,6 +413,7 @@ typedef struct _xmlDtd xmlDtd; typedef xmlDtd *xmlDtdPtr; struct _xmlDtd { void *_private; /* application data */ + void *_private2; xmlElementType type; /* XML_DTD_NODE, must be second ! */ const xmlChar *name; /* Name of the DTD */ struct _xmlNode *children; /* the value of the property link */ @@ -438,6 +442,7 @@ typedef struct _xmlAttr xmlAttr; typedef xmlAttr *xmlAttrPtr; struct _xmlAttr { void *_private; /* application data */ + void *_private2; xmlElementType type; /* XML_ATTRIBUTE_NODE, must be second ! */ const xmlChar *name; /* the name of the property */ struct _xmlNode *children; /* the value of the property */ @@ -493,6 +498,7 @@ typedef struct _xmlNode xmlNode; typedef xmlNode *xmlNodePtr; struct _xmlNode { void *_private; /* application data */ + void *_private2; /* application data, slot 2 */ xmlElementType type; /* type number, must be second ! */ const xmlChar *name; /* the name of the node, or the entity */ struct _xmlNode *children; /* parent->childs link */ @@ -555,6 +561,7 @@ typedef struct _xmlDoc xmlDoc; typedef xmlDoc *xmlDocPtr; struct _xmlDoc { void *_private; /* application data */ + void *_private2; xmlElementType type; /* XML_DOCUMENT_NODE, must be second ! */ char *name; /* name/filename/URI of the document */ struct _xmlNode *children; /* the document tree */ diff --git a/libs/xml2/xpath.c b/libs/xml2/xpath.c index 660d70e50fd..31efaecf23b 100644 --- a/libs/xml2/xpath.c +++ b/libs/xml2/xpath.c @@ -227,6 +227,7 @@ xmlXPathIsInf(double val) { */ static xmlNs xmlXPathXMLNamespaceStruct = { + NULL, NULL, XML_NAMESPACE_DECL, XML_XML_NAMESPACE, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10599
v2: enable more tests on Wine -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10599#note_135473
participants (2)
-
Nikolay Sivov -
Nikolay Sivov (@nsivov)