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
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};
/* 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,
* and also need access to it from the libxml backend. */
typedef struct _domdoc_properties {
VARIANT_BOOL preserving;
IXMLDOMSchemaCollection2* schemaCache;
struct list selectNsList;
xmlChar const* selectNsStr;
LONG selectNsStr_len;
......@@ -116,7 +118,6 @@ struct domdoc
VARIANT_BOOL validating;
VARIANT_BOOL resolving;
domdoc_properties* properties;
IXMLDOMSchemaCollection2* schema;
bsc_t *bsc;
HRESULT error;
......@@ -245,9 +246,9 @@ static domdoc_properties * create_properties(const GUID *clsid)
list_init( &properties->selectNsList );
properties->preserving = VARIANT_FALSE;
properties->schemaCache = NULL;
properties->selectNsStr = heap_alloc_zero(sizeof(xmlChar));
properties->selectNsStr_len = 0;
properties->XPath = FALSE;
/* properties that are dependent on object versions */
if (IsEqualCLSID( clsid, &CLSID_DOMDocument40 ) ||
......@@ -255,6 +256,10 @@ static domdoc_properties * create_properties(const GUID *clsid)
{
properties->XPath = TRUE;
}
else
{
properties->XPath = FALSE;
}
return properties;
}
......@@ -270,6 +275,7 @@ static domdoc_properties* copy_properties(domdoc_properties const* properties)
if (pcopy)
{
pcopy->preserving = properties->preserving;
pcopy->schemaCache = properties->schemaCache;
pcopy->XPath = properties->XPath;
pcopy->selectNsStr_len = properties->selectNsStr_len;
list_init( &pcopy->selectNsList );
......@@ -295,6 +301,8 @@ static void free_properties(domdoc_properties* properties)
{
if (properties)
{
if (properties->schemaCache)
IXMLDOMSchemaCollection2_Release(properties->schemaCache);
clear_selectNsList(&properties->selectNsList);
heap_free((xmlChar*)properties->selectNsStr);
heap_free(properties);
......@@ -886,8 +894,8 @@ static ULONG WINAPI domdoc_Release(
if (This->site)
IUnknown_Release( This->site );
destroy_xmlnode(&This->node);
if(This->schema) IXMLDOMSchemaCollection2_Release(This->schema);
if (This->stream) IStream_Release(This->stream);
if (This->stream)
IStream_Release(This->stream);
heap_free(This);
}
......@@ -2454,7 +2462,7 @@ static HRESULT WINAPI domdoc_get_schemas(
{
domdoc *This = impl_from_IXMLDOMDocument3( iface );
HRESULT hr = S_FALSE;
IXMLDOMSchemaCollection2* cur_schema = This->schema;
IXMLDOMSchemaCollection2* cur_schema = This->properties->schemaCache;
TRACE("(%p)->(%p)\n", This, var1);
......@@ -2500,7 +2508,7 @@ static HRESULT WINAPI domdoc_putref_schemas(
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);
}
......@@ -2615,10 +2623,10 @@ static HRESULT WINAPI domdoc_validateNode(
}
/* 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))
{
++validated;
......@@ -3332,7 +3340,6 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **docu
doc->resolving = 0;
doc->properties = properties_from_xmlDocPtr(xmldoc);
doc->error = S_OK;
doc->schema = NULL;
doc->stream = NULL;
doc->site = NULL;
doc->safeopt = 0;
......
......@@ -7311,96 +7311,158 @@ static void test_removeQualifiedItem(void)
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)
{
IXMLDOMDocument *doc1, *doc2, *doc3;
IXMLDOMDocument2 *doc, *doc_owner;
IXMLDOMNode *node;
IXMLDOMSchemaCollection *cache;
VARIANT_BOOL b;
VARIANT var;
HRESULT hr;
BSTR str;
doc = create_document(&IID_IXMLDOMDocument2);
if (!doc) return;
str = SysAllocString( szComplete4 );
hr = IXMLDOMDocument_loadXML( doc, str, &b );
ok( hr == S_OK, "loadXML failed\n");
ok( b == VARIANT_TRUE, "failed to load XML string\n");
SysFreeString( str );
cache = create_cache(&IID_IXMLDOMSchemaCollection);
if (!doc || !cache)
{
if (doc) IXMLDOMDocument2_Release(doc);
if (cache) IXMLDOMSchemaCollection_Release(cache);
return;
}
hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var);
ok( hr == S_OK, "got 0x%08x\n", hr);
ok( lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
VariantClear(&var);
VariantInit(&var);
/* set to XPath and check that new instances use it */
hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"));
ok( hr == S_OK, "got 0x%08x\n", hr);
str = SysAllocString(szComplete4);
ole_check(IXMLDOMDocument_loadXML(doc, str, &b));
ok(b == VARIANT_TRUE, "failed to load XML string\n");
SysFreeString(str);
hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'"));
ok( hr == S_OK, "got 0x%08x\n", hr);
check_default_props(doc);
hr = IXMLDOMDocument2_get_firstChild(doc, &node);
ok( hr == S_OK, "got 0x%08x\n", hr);
/* set properties and check that new instances use them */
set_props(doc, cache);
check_set_props(doc);
hr = IXMLDOMNode_get_ownerDocument(node, &doc1);
ok( hr == S_OK, "got 0x%08x\n", hr);
ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
hr = IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner);
ok( hr == S_OK, "got 0x%08x\n", hr);
/* new interface keeps props */
ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
hr = IXMLDOMDocument2_getProperty(doc_owner, _bstr_("SelectionNamespaces"), &var);
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);
check_set_props(doc_owner);
IXMLDOMDocument2_Release(doc_owner);
hr = IXMLDOMNode_get_ownerDocument(node, &doc2);
ok( hr == S_OK, "got 0x%08x\n", hr);
ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
IXMLDOMNode_Release(node);
ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
/* reload */
str = SysAllocString( szComplete4 );
hr = IXMLDOMDocument2_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 );
str = SysAllocString(szComplete4);
ole_check(IXMLDOMDocument2_loadXML(doc, str, &b));
ok(b == VARIANT_TRUE, "failed to load XML string\n");
SysFreeString(str);
/* properties retained even after reload */
hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var);
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);
check_set_props(doc);
hr = IXMLDOMNode_get_ownerDocument(node, &doc3);
ok( hr == S_OK, "got 0x%08x\n", hr);
ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
IXMLDOMNode_Release(node);
hr = IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner);
ok( hr == S_OK, "got 0x%08x\n", hr);
ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
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(doc2);
IXMLDOMDocument_Release(doc3);
IXMLDOMDocument2_Release(doc);
IXMLDOMDocument2_Release(doc_owner);
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