Commit b7cdaba8 authored by Adam Martinson's avatar Adam Martinson Committed by Alexandre Julliard

msxml3: Move schema cache into the domdoc_properties struct.

parent bc56bbfb
...@@ -70,11 +70,13 @@ static const WCHAR PropertyNewParserW[] = {'N','e','w','P','a','r','s','e','r',0 ...@@ -70,11 +70,13 @@ static const WCHAR PropertyNewParserW[] = {'N','e','w','P','a','r','s','e','r',0
static const WCHAR PropValueXPathW[] = {'X','P','a','t','h',0}; static const WCHAR PropValueXPathW[] = {'X','P','a','t','h',0};
static const WCHAR PropValueXSLPatternW[] = {'X','S','L','P','a','t','t','e','r','n',0}; static const WCHAR PropValueXSLPatternW[] = {'X','S','L','P','a','t','t','e','r','n',0};
/* Data used by domdoc_getProperty()/domdoc_setProperty(). /* 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, * We need to preserve this when reloading a document,
* and also need access to it from the libxml backend. */ * and also need access to it from the libxml backend. */
typedef struct _domdoc_properties { typedef struct _domdoc_properties {
VARIANT_BOOL preserving; VARIANT_BOOL preserving;
IXMLDOMSchemaCollection2* schemaCache;
struct list selectNsList; struct list selectNsList;
xmlChar const* selectNsStr; xmlChar const* selectNsStr;
LONG selectNsStr_len; LONG selectNsStr_len;
...@@ -116,7 +118,6 @@ struct domdoc ...@@ -116,7 +118,6 @@ struct domdoc
VARIANT_BOOL validating; VARIANT_BOOL validating;
VARIANT_BOOL resolving; VARIANT_BOOL resolving;
domdoc_properties* properties; domdoc_properties* properties;
IXMLDOMSchemaCollection2* schema;
bsc_t *bsc; bsc_t *bsc;
HRESULT error; HRESULT error;
...@@ -245,9 +246,9 @@ static domdoc_properties * create_properties(const GUID *clsid) ...@@ -245,9 +246,9 @@ static domdoc_properties * create_properties(const GUID *clsid)
list_init( &properties->selectNsList ); list_init( &properties->selectNsList );
properties->preserving = VARIANT_FALSE; properties->preserving = VARIANT_FALSE;
properties->schemaCache = NULL;
properties->selectNsStr = heap_alloc_zero(sizeof(xmlChar)); properties->selectNsStr = heap_alloc_zero(sizeof(xmlChar));
properties->selectNsStr_len = 0; properties->selectNsStr_len = 0;
properties->XPath = FALSE;
/* properties that are dependent on object versions */ /* properties that are dependent on object versions */
if (IsEqualCLSID( clsid, &CLSID_DOMDocument40 ) || if (IsEqualCLSID( clsid, &CLSID_DOMDocument40 ) ||
...@@ -255,6 +256,10 @@ static domdoc_properties * create_properties(const GUID *clsid) ...@@ -255,6 +256,10 @@ static domdoc_properties * create_properties(const GUID *clsid)
{ {
properties->XPath = TRUE; properties->XPath = TRUE;
} }
else
{
properties->XPath = FALSE;
}
return properties; return properties;
} }
...@@ -270,6 +275,7 @@ static domdoc_properties* copy_properties(domdoc_properties const* properties) ...@@ -270,6 +275,7 @@ static domdoc_properties* copy_properties(domdoc_properties const* properties)
if (pcopy) if (pcopy)
{ {
pcopy->preserving = properties->preserving; pcopy->preserving = properties->preserving;
pcopy->schemaCache = properties->schemaCache;
pcopy->XPath = properties->XPath; pcopy->XPath = properties->XPath;
pcopy->selectNsStr_len = properties->selectNsStr_len; pcopy->selectNsStr_len = properties->selectNsStr_len;
list_init( &pcopy->selectNsList ); list_init( &pcopy->selectNsList );
...@@ -295,6 +301,8 @@ static void free_properties(domdoc_properties* properties) ...@@ -295,6 +301,8 @@ static void free_properties(domdoc_properties* properties)
{ {
if (properties) if (properties)
{ {
if (properties->schemaCache)
IXMLDOMSchemaCollection2_Release(properties->schemaCache);
clear_selectNsList(&properties->selectNsList); clear_selectNsList(&properties->selectNsList);
heap_free((xmlChar*)properties->selectNsStr); heap_free((xmlChar*)properties->selectNsStr);
heap_free(properties); heap_free(properties);
...@@ -886,8 +894,8 @@ static ULONG WINAPI domdoc_Release( ...@@ -886,8 +894,8 @@ static ULONG WINAPI domdoc_Release(
if (This->site) if (This->site)
IUnknown_Release( This->site ); IUnknown_Release( This->site );
destroy_xmlnode(&This->node); destroy_xmlnode(&This->node);
if(This->schema) IXMLDOMSchemaCollection2_Release(This->schema); if (This->stream)
if (This->stream) IStream_Release(This->stream); IStream_Release(This->stream);
heap_free(This); heap_free(This);
} }
...@@ -2454,7 +2462,7 @@ static HRESULT WINAPI domdoc_get_schemas( ...@@ -2454,7 +2462,7 @@ static HRESULT WINAPI domdoc_get_schemas(
{ {
domdoc *This = impl_from_IXMLDOMDocument3( iface ); domdoc *This = impl_from_IXMLDOMDocument3( iface );
HRESULT hr = S_FALSE; HRESULT hr = S_FALSE;
IXMLDOMSchemaCollection2* cur_schema = This->schema; IXMLDOMSchemaCollection2* cur_schema = This->properties->schemaCache;
TRACE("(%p)->(%p)\n", This, var1); TRACE("(%p)->(%p)\n", This, var1);
...@@ -2500,7 +2508,7 @@ static HRESULT WINAPI domdoc_putref_schemas( ...@@ -2500,7 +2508,7 @@ static HRESULT WINAPI domdoc_putref_schemas(
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
IXMLDOMSchemaCollection2* old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema); IXMLDOMSchemaCollection2* old_schema = InterlockedExchangePointer((void**)&This->properties->schemaCache, new_schema);
if(old_schema) IXMLDOMSchemaCollection2_Release(old_schema); if(old_schema) IXMLDOMSchemaCollection2_Release(old_schema);
} }
...@@ -2615,10 +2623,10 @@ static HRESULT WINAPI domdoc_validateNode( ...@@ -2615,10 +2623,10 @@ static HRESULT WINAPI domdoc_validateNode(
} }
/* Schema validation */ /* Schema validation */
if (hr == S_OK && This->schema != NULL) if (hr == S_OK && This->properties->schemaCache != NULL)
{ {
hr = SchemaCache_validate_tree(This->schema, get_node_obj(node)->node); hr = SchemaCache_validate_tree(This->properties->schemaCache, get_node_obj(node)->node);
if (!FAILED(hr)) if (!FAILED(hr))
{ {
++validated; ++validated;
...@@ -3332,7 +3340,6 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **docu ...@@ -3332,7 +3340,6 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **docu
doc->resolving = 0; doc->resolving = 0;
doc->properties = properties_from_xmlDocPtr(xmldoc); doc->properties = properties_from_xmlDocPtr(xmldoc);
doc->error = S_OK; doc->error = S_OK;
doc->schema = NULL;
doc->stream = NULL; doc->stream = NULL;
doc->site = NULL; doc->site = NULL;
doc->safeopt = 0; doc->safeopt = 0;
......
...@@ -7311,96 +7311,158 @@ static void test_removeQualifiedItem(void) ...@@ -7311,96 +7311,158 @@ static void test_removeQualifiedItem(void)
free_bstrs(); free_bstrs();
} }
#define check_default_props(doc) _check_default_props(__LINE__, doc)
static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
{
VARIANT_BOOL b;
VARIANT var;
HRESULT hr;
VariantInit(&var);
helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
VariantClear(&var);
helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
VariantClear(&var);
helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
hr = IXMLDOMDocument2_get_schemas(doc, &var);
ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
VariantClear(&var);
}
#define check_set_props(doc) _check_set_props(__LINE__, doc)
static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
{
VARIANT_BOOL b;
VARIANT var;
VariantInit(&var);
helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
VariantClear(&var);
helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
VariantClear(&var);
helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
VariantClear(&var);
}
#define set_props(doc, cache) _set_props(__LINE__, doc, cache)
static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
{
VARIANT var;
VariantInit(&var);
helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
V_VT(&var) = VT_DISPATCH;
V_DISPATCH(&var) = NULL;
helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
VariantClear(&var);
}
#define unset_props(doc) _unset_props(__LINE__, doc)
static inline void _unset_props(int line, IXMLDOMDocument2* doc)
{
VARIANT var;
VariantInit(&var);
helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
V_VT(&var) = VT_NULL;
helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
VariantClear(&var);
}
static void test_get_ownerDocument(void) static void test_get_ownerDocument(void)
{ {
IXMLDOMDocument *doc1, *doc2, *doc3; IXMLDOMDocument *doc1, *doc2, *doc3;
IXMLDOMDocument2 *doc, *doc_owner; IXMLDOMDocument2 *doc, *doc_owner;
IXMLDOMNode *node; IXMLDOMNode *node;
IXMLDOMSchemaCollection *cache;
VARIANT_BOOL b; VARIANT_BOOL b;
VARIANT var; VARIANT var;
HRESULT hr;
BSTR str; BSTR str;
doc = create_document(&IID_IXMLDOMDocument2); doc = create_document(&IID_IXMLDOMDocument2);
if (!doc) return; cache = create_cache(&IID_IXMLDOMSchemaCollection);
if (!doc || !cache)
str = SysAllocString( szComplete4 ); {
hr = IXMLDOMDocument_loadXML( doc, str, &b ); if (doc) IXMLDOMDocument2_Release(doc);
ok( hr == S_OK, "loadXML failed\n"); if (cache) IXMLDOMSchemaCollection_Release(cache);
ok( b == VARIANT_TRUE, "failed to load XML string\n"); return;
SysFreeString( str ); }
hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var); VariantInit(&var);
ok( hr == S_OK, "got 0x%08x\n", hr);
ok( lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
VariantClear(&var);
/* set to XPath and check that new instances use it */ str = SysAllocString(szComplete4);
hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")); ole_check(IXMLDOMDocument_loadXML(doc, str, &b));
ok( hr == S_OK, "got 0x%08x\n", hr); ok(b == VARIANT_TRUE, "failed to load XML string\n");
SysFreeString(str);
hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")); check_default_props(doc);
ok( hr == S_OK, "got 0x%08x\n", hr);
hr = IXMLDOMDocument2_get_firstChild(doc, &node); /* set properties and check that new instances use them */
ok( hr == S_OK, "got 0x%08x\n", hr); set_props(doc, cache);
check_set_props(doc);
hr = IXMLDOMNode_get_ownerDocument(node, &doc1); ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
ok( hr == S_OK, "got 0x%08x\n", hr); ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
hr = IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner); /* new interface keeps props */
ok( hr == S_OK, "got 0x%08x\n", hr); ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc); ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
hr = IXMLDOMDocument2_getProperty(doc_owner, _bstr_("SelectionNamespaces"), &var); check_set_props(doc_owner);
ok( hr == S_OK, "got 0x%08x\n", hr);
ok( lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "expected previously set value\n");
VariantClear(&var);
hr = IXMLDOMDocument2_getProperty(doc_owner, _bstr_("SelectionLanguage"), &var);
ok( hr == S_OK, "got 0x%08x\n", hr);
ok( lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
VariantClear(&var);
IXMLDOMDocument2_Release(doc_owner); IXMLDOMDocument2_Release(doc_owner);
hr = IXMLDOMNode_get_ownerDocument(node, &doc2); ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
ok( hr == S_OK, "got 0x%08x\n", hr);
IXMLDOMNode_Release(node); IXMLDOMNode_Release(node);
ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc); ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
/* reload */ /* reload */
str = SysAllocString( szComplete4 ); str = SysAllocString(szComplete4);
hr = IXMLDOMDocument2_loadXML( doc, str, &b ); ole_check(IXMLDOMDocument2_loadXML(doc, str, &b));
ok( hr == S_OK, "got 0x%08x\n", hr); ok(b == VARIANT_TRUE, "failed to load XML string\n");
ok( b == VARIANT_TRUE, "failed to load XML string\n"); SysFreeString(str);
SysFreeString( str );
/* properties retained even after reload */ /* properties retained even after reload */
hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var); check_set_props(doc);
ok( hr == S_OK, "got 0x%08x\n", hr);
ok( lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "expected previously set value\n");
VariantClear(&var);
hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var);
ok( hr == S_OK, "got 0x%08x\n", hr);
ok( lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
VariantClear(&var);
hr = IXMLDOMDocument2_get_firstChild(doc, &node);
ok( hr == S_OK, "got 0x%08x\n", hr);
hr = IXMLDOMNode_get_ownerDocument(node, &doc3); ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
ok( hr == S_OK, "got 0x%08x\n", hr); ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
IXMLDOMNode_Release(node); IXMLDOMNode_Release(node);
hr = IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner); ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
ok( hr == S_OK, "got 0x%08x\n", hr);
ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2); ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
check_set_props(doc_owner);
/* changing properties for one instance changes them for all */
unset_props(doc_owner);
check_default_props(doc_owner);
check_default_props(doc);
IXMLDOMDocument_Release(doc1); IXMLDOMDocument_Release(doc1);
IXMLDOMDocument_Release(doc2); IXMLDOMDocument_Release(doc2);
IXMLDOMDocument_Release(doc3); IXMLDOMDocument_Release(doc3);
IXMLDOMDocument2_Release(doc); IXMLDOMDocument2_Release(doc);
IXMLDOMDocument2_Release(doc_owner);
free_bstrs(); free_bstrs();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment