From 43241140aaa1bf0f7cee277488e599ae721d4d59 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sun, 22 Apr 2012 23:30:22 +0400 Subject: [PATCH] msxml3: Implement push/pop operations for contexts. --- dlls/msxml3/mxnamespace.c | 46 ++++++++++++++++++-- dlls/msxml3/tests/domdoc.c | 89 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 4 deletions(-) diff --git a/dlls/msxml3/mxnamespace.c b/dlls/msxml3/mxnamespace.c index f21c758f321..f7d4eb6260b 100644 --- a/dlls/msxml3/mxnamespace.c +++ b/dlls/msxml3/mxnamespace.c @@ -184,11 +184,22 @@ static struct nscontext* alloc_ns_context(void) ctxt->count = 0; ctxt->max_alloc = DEFAULT_PREFIX_ALLOC_COUNT; ctxt->ns = heap_alloc(ctxt->max_alloc*sizeof(*ctxt->ns)); + if (!ctxt->ns) + { + heap_free(ctxt); + return NULL; + } /* first allocated prefix is always 'xml' */ ctxt->ns[0].prefix = SysAllocString(xmlW); ctxt->ns[0].uri = SysAllocString(xmluriW); ctxt->count++; + if (!ctxt->ns[0].prefix || !ctxt->ns[0].uri) + { + heap_free(ctxt->ns); + heap_free(ctxt); + return NULL; + } return ctxt; } @@ -521,8 +532,16 @@ static HRESULT WINAPI vbnamespacemanager_reset(IVBMXNamespaceManager *iface) static HRESULT WINAPI vbnamespacemanager_pushContext(IVBMXNamespaceManager *iface) { namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); - FIXME("(%p): stub\n", This); - return E_NOTIMPL; + struct nscontext *ctxt; + + TRACE("(%p)\n", This); + + ctxt = alloc_ns_context(); + if (!ctxt) return E_OUTOFMEMORY; + + list_add_head(&This->ctxts, &ctxt->entry); + + return S_OK; } static HRESULT WINAPI vbnamespacemanager_pushNodeContext(IVBMXNamespaceManager *iface, @@ -536,8 +555,20 @@ static HRESULT WINAPI vbnamespacemanager_pushNodeContext(IVBMXNamespaceManager * static HRESULT WINAPI vbnamespacemanager_popContext(IVBMXNamespaceManager *iface) { namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); - FIXME("(%p): stub\n", This); - return E_NOTIMPL; + const struct list *next; + struct nscontext *ctxt; + + TRACE("(%p)\n", This); + + next = list_next(&This->ctxts, list_head(&This->ctxts)); + if (!next) return E_FAIL; + + ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry); + list_remove(list_head(&This->ctxts)); + + free_ns_context(ctxt); + + return S_OK; } static HRESULT WINAPI vbnamespacemanager_declarePrefix(IVBMXNamespaceManager *iface, @@ -605,6 +636,7 @@ static const tid_t namespacemanager_iface_tids[] = { IVBMXNamespaceManager_tid, 0 }; + static dispex_static_data_t namespacemanager_dispex = { NULL, IVBMXNamespaceManager_tid, @@ -630,6 +662,12 @@ HRESULT MXNamespaceManager_create(IUnknown *outer, void **obj) list_init(&This->ctxts); ctxt = alloc_ns_context(); + if (!ctxt) + { + heap_free(This); + return E_OUTOFMEMORY; + } + list_add_head(&This->ctxts, &ctxt->entry); This->override = VARIANT_TRUE; diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 258cca35f87..ccc2c64dac7 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -10716,6 +10716,95 @@ todo_wine { IMXNamespaceManager_Release(nsmgr); + /* push/pop tests */ + hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER, + &IID_IMXNamespaceManager, (void**)&nsmgr); + EXPECT_HR(hr, S_OK); + + /* pop with empty stack */ + hr = IMXNamespaceManager_popContext(nsmgr); + EXPECT_HR(hr, E_FAIL); + + hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri")); + EXPECT_HR(hr, S_OK); + + len = 100; + buffW[0] = 0x1; + hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW)); + ok(len == 3, "got %d\n", len); + + hr = IMXNamespaceManager_pushContext(nsmgr); + EXPECT_HR(hr, S_OK); + + len = 100; + buffW[0] = 0x1; + hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len); +todo_wine + EXPECT_HR(hr, S_OK); + if (hr == S_OK) { + ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW)); + ok(len == 3, "got %d\n", len); + } + + hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri")); + EXPECT_HR(hr, S_OK); + + len = 100; + buffW[0] = 0x1; + hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW)); + ok(len == 3, "got %d\n", len); + + hr = IMXNamespaceManager_pushContext(nsmgr); + EXPECT_HR(hr, S_OK); + hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns3"), _bstr_("ns3 uri")); + EXPECT_HR(hr, S_OK); + + len = 100; + buffW[0] = 0x1; + hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len); +todo_wine + EXPECT_HR(hr, S_OK); + if (hr == S_OK) { + ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW)); + ok(len == 3, "got %d\n", len); + } + + len = 100; + buffW[0] = 0x1; + hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len); +todo_wine + EXPECT_HR(hr, S_OK); + if (hr == S_OK) { + ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW)); + ok(len == 3, "got %d\n", len); + } + + hr = IMXNamespaceManager_popContext(nsmgr); + EXPECT_HR(hr, S_OK); + + hr = IMXNamespaceManager_popContext(nsmgr); + EXPECT_HR(hr, S_OK); + + len = 100; + buffW[0] = 0x1; + hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len); + EXPECT_HR(hr, E_FAIL); + ok(buffW[0] == 0x1, "got %x\n", buffW[0]); + ok(len == 100, "got %d\n", len); + + len = 100; + buffW[0] = 0x1; + hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW)); + ok(len == 3, "got %d\n", len); + + IMXNamespaceManager_Release(nsmgr); + free_bstrs(); }