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