Huw Davies : msxml3: Implement {get,putref}_schemas.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Feb 28 08:19:00 CST 2007
Module: wine
Branch: master
Commit: 1780ca678c372e2f788383eccf0bfa0b4853deba
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1780ca678c372e2f788383eccf0bfa0b4853deba
Author: Huw Davies <huw at codeweavers.com>
Date: Tue Feb 27 15:11:13 2007 +0000
msxml3: Implement {get,putref}_schemas.
---
dlls/msxml3/domdoc.c | 66 ++++++++++++++++++++++----
dlls/msxml3/schema.c | 1 +
dlls/msxml3/tests/schema.c | 110 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 167 insertions(+), 10 deletions(-)
diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index 1e2d8cd..8b3f561 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -171,6 +171,7 @@ typedef struct _domdoc
VARIANT_BOOL preserving;
IUnknown *node_unk;
IXMLDOMNode *node;
+ IXMLDOMSchemaCollection *schema;
HRESULT error;
} domdoc;
@@ -254,6 +255,7 @@ static ULONG WINAPI domdoc_Release(
if ( ref == 0 )
{
IUnknown_Release( This->node_unk );
+ if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
HeapFree( GetProcessHeap(), 0, This );
}
@@ -1293,7 +1295,7 @@ static HRESULT WINAPI domdoc_put_onTransformNode(
}
static HRESULT WINAPI domdoc_get_namespaces(
- IXMLDOMDocument2* This,
+ IXMLDOMDocument2* iface,
IXMLDOMSchemaCollection** schemaCollection )
{
FIXME("\n");
@@ -1301,23 +1303,66 @@ static HRESULT WINAPI domdoc_get_namespaces(
}
static HRESULT WINAPI domdoc_get_schemas(
- IXMLDOMDocument2* This,
+ IXMLDOMDocument2* iface,
VARIANT* var1 )
{
- FIXME("\n");
- return E_NOTIMPL;
+ domdoc *This = impl_from_IXMLDOMDocument2( iface );
+ HRESULT hr = S_FALSE;
+ IXMLDOMSchemaCollection *cur_schema = This->schema;
+
+ TRACE("(%p)->(%p)\n", This, var1);
+
+ VariantInit(var1); /* Test shows we don't call VariantClear here */
+ V_VT(var1) = VT_NULL;
+
+ if(cur_schema)
+ {
+ hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
+ if(SUCCEEDED(hr))
+ V_VT(var1) = VT_DISPATCH;
+ }
+ return hr;
}
static HRESULT WINAPI domdoc_putref_schemas(
- IXMLDOMDocument2* This,
+ IXMLDOMDocument2* iface,
VARIANT var1)
{
- FIXME("\n");
- return E_NOTIMPL;
+ domdoc *This = impl_from_IXMLDOMDocument2( iface );
+ HRESULT hr = E_FAIL;
+ IXMLDOMSchemaCollection *new_schema = NULL;
+
+ FIXME("(%p): semi-stub\n", This);
+ switch(V_VT(&var1))
+ {
+ case VT_UNKNOWN:
+ hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
+ break;
+
+ case VT_DISPATCH:
+ hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
+ break;
+
+ case VT_NULL:
+ case VT_EMPTY:
+ hr = S_OK;
+ break;
+
+ default:
+ WARN("Can't get schema from vt %x\n", V_VT(&var1));
+ }
+
+ if(SUCCEEDED(hr))
+ {
+ IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
+ if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
+ }
+
+ return hr;
}
static HRESULT WINAPI domdoc_validate(
- IXMLDOMDocument2* This,
+ IXMLDOMDocument2* iface,
IXMLDOMParseError** err)
{
FIXME("\n");
@@ -1325,7 +1370,7 @@ static HRESULT WINAPI domdoc_validate(
}
static HRESULT WINAPI domdoc_setProperty(
- IXMLDOMDocument2* This,
+ IXMLDOMDocument2* iface,
BSTR p,
VARIANT var)
{
@@ -1334,7 +1379,7 @@ static HRESULT WINAPI domdoc_setProperty(
}
static HRESULT WINAPI domdoc_getProperty(
- IXMLDOMDocument2* This,
+ IXMLDOMDocument2* iface,
BSTR p,
VARIANT* var)
{
@@ -1447,6 +1492,7 @@ HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
doc->resolving = 0;
doc->preserving = 0;
doc->error = S_OK;
+ doc->schema = NULL;
xmldoc = xmlNewDoc(NULL);
if(!xmldoc)
diff --git a/dlls/msxml3/schema.c b/dlls/msxml3/schema.c
index f823e78..5d48321 100644
--- a/dlls/msxml3/schema.c
+++ b/dlls/msxml3/schema.c
@@ -55,6 +55,7 @@ static HRESULT WINAPI schema_cache_QueryInterface( IXMLDOMSchemaCollection *ifac
TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
if ( IsEqualIID( riid, &IID_IUnknown ) ||
+ IsEqualIID( riid, &IID_IDispatch ) ||
IsEqualIID( riid, &IID_IXMLDOMSchemaCollection ) )
{
*ppvObject = iface;
diff --git a/dlls/msxml3/tests/schema.c b/dlls/msxml3/tests/schema.c
index 8651aa9..b012621 100644
--- a/dlls/msxml3/tests/schema.c
+++ b/dlls/msxml3/tests/schema.c
@@ -86,8 +86,118 @@ void test_schema_refs(void)
SysFreeString(str);
VariantClear(&v);
+ V_VT(&v) = VT_INT;
+ r = IXMLDOMDocument2_get_schemas(doc, &v);
+ ok(r == S_FALSE, "ret %08x\n", r);
+ ok(V_VT(&v) == VT_NULL, "vt %x\n", V_VT(&v));
+
+ ref = IXMLDOMSchemaCollection_AddRef(schema);
+ ok(ref == 2, "ref %d\n", ref);
+ V_VT(&v) = VT_DISPATCH;
+ V_DISPATCH(&v) = (IDispatch*)schema;
+
+ /* check that putref_schemas takes a ref */
+ r = IXMLDOMDocument2_putref_schemas(doc, v);
+ ok(r == S_OK, "ret %08x\n", r);
+ ref = IXMLDOMSchemaCollection_AddRef(schema);
+ ok(ref == 4, "ref %d\n", ref);
+ IXMLDOMSchemaCollection_Release(schema);
+ VariantClear(&v);
+
+ /* refs now 2 */
+ V_VT(&v) = VT_INT;
+ /* check that get_schemas adds a ref */
+ r = IXMLDOMDocument2_get_schemas(doc, &v);
+ ok(r == S_OK, "ret %08x\n", r);
+ ok(V_VT(&v) == VT_DISPATCH, "vt %x\n", V_VT(&v));
+ ref = IXMLDOMSchemaCollection_AddRef(schema);
+ ok(ref == 4, "ref %d\n", ref);
+ IXMLDOMSchemaCollection_Release(schema);
+
+ /* refs now 3 */
+ /* get_schemas doesn't release a ref if passed VT_DISPATCH - ie it doesn't call VariantClear() */
+ r = IXMLDOMDocument2_get_schemas(doc, &v);
+ ok(r == S_OK, "ret %08x\n", r);
+ ok(V_VT(&v) == VT_DISPATCH, "vt %x\n", V_VT(&v));
+ ref = IXMLDOMSchemaCollection_AddRef(schema);
+ ok(ref == 5, "ref %d\n", ref);
+ IXMLDOMSchemaCollection_Release(schema);
+
+ /* refs now 4 */
+ /* release the two refs returned by get_schemas */
+ IXMLDOMSchemaCollection_Release(schema);
+ IXMLDOMSchemaCollection_Release(schema);
+
+ /* refs now 2 */
+
+ /* check that taking another ref on the document doesn't change the schema's ref count */
+ IXMLDOMDocument2_AddRef(doc);
+ ref = IXMLDOMSchemaCollection_AddRef(schema);
+ ok(ref == 3, "ref %d\n", ref);
+ IXMLDOMSchemaCollection_Release(schema);
+ IXMLDOMDocument2_Release(doc);
+
+
+ /* refs now 2 */
+ /* call putref_schema with some odd variants */
+ V_VT(&v) = VT_INT;
+ r = IXMLDOMDocument2_putref_schemas(doc, v);
+ ok(r == E_FAIL, "ret %08x\n", r);
+ ref = IXMLDOMSchemaCollection_AddRef(schema);
+ ok(ref == 3, "ref %d\n", ref);
+ IXMLDOMSchemaCollection_Release(schema);
+
+ /* refs now 2 */
+ /* calling with VT_EMPTY releases the schema */
+ V_VT(&v) = VT_EMPTY;
+ r = IXMLDOMDocument2_putref_schemas(doc, v);
+ ok(r == S_OK, "ret %08x\n", r);
+ ref = IXMLDOMSchemaCollection_AddRef(schema);
+ ok(ref == 2, "ref %d\n", ref);
+ IXMLDOMSchemaCollection_Release(schema);
+
+ /* refs now 1 */
+ /* try setting with VT_UNKNOWN */
+ IXMLDOMSchemaCollection_AddRef(schema);
+ V_VT(&v) = VT_UNKNOWN;
+ V_UNKNOWN(&v) = (IUnknown*)schema;
+ r = IXMLDOMDocument2_putref_schemas(doc, v);
+ ok(r == S_OK, "ret %08x\n", r);
+ ref = IXMLDOMSchemaCollection_AddRef(schema);
+ ok(ref == 4, "ref %d\n", ref);
IXMLDOMSchemaCollection_Release(schema);
+ VariantClear(&v);
+
+ /* refs now 2 */
+ /* calling with VT_NULL releases the schema */
+ V_VT(&v) = VT_NULL;
+ r = IXMLDOMDocument2_putref_schemas(doc, v);
+ ok(r == S_OK, "ret %08x\n", r);
+ ref = IXMLDOMSchemaCollection_AddRef(schema);
+ ok(ref == 2, "ref %d\n", ref);
+ IXMLDOMSchemaCollection_Release(schema);
+
+ /* refs now 1 */
+ /* set again */
+ IXMLDOMSchemaCollection_AddRef(schema);
+ V_VT(&v) = VT_UNKNOWN;
+ V_UNKNOWN(&v) = (IUnknown*)schema;
+ r = IXMLDOMDocument2_putref_schemas(doc, v);
+ ok(r == S_OK, "ret %08x\n", r);
+ ref = IXMLDOMSchemaCollection_AddRef(schema);
+ ok(ref == 4, "ref %d\n", ref);
+ IXMLDOMSchemaCollection_Release(schema);
+ VariantClear(&v);
+
+ /* refs now 2 */
+
+ /* release the final ref on the doc which should release its ref on the schema */
IXMLDOMDocument2_Release(doc);
+
+ ref = IXMLDOMSchemaCollection_AddRef(schema);
+ ok(ref == 2, "ref %d\n", ref);
+ IXMLDOMSchemaCollection_Release(schema);
+ IXMLDOMSchemaCollection_Release(schema);
}
START_TEST(schema)
More information about the wine-cvs
mailing list