oleacc: Added CAccPropServices stub implementation.
[wine/multimedia.git] / dlls / msxml3 / mxnamespace.c
blobf114d973445a884e2e91224c3d9470ef1c5a91d4
1 /*
2 * IMXNamespaceManager implementation
4 * Copyright 2011-2012 Nikolay Sivov for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #define NONAMELESSUNION
24 #include "config.h"
26 #include <stdarg.h>
27 #ifdef HAVE_LIBXML2
28 # include <libxml/parser.h>
29 # include <libxml/xmlerror.h>
30 # include <libxml/encoding.h>
31 #endif
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winuser.h"
36 #include "ole2.h"
37 #include "msxml6.h"
39 #include "msxml_private.h"
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
45 struct ns
47 BSTR prefix;
48 BSTR uri;
51 struct nscontext
53 struct list entry;
55 struct ns *ns;
56 int count;
57 int max_alloc;
60 #define DEFAULT_PREFIX_ALLOC_COUNT 16
62 static const WCHAR xmlW[] = {'x','m','l',0};
63 static const WCHAR xmluriW[] = {'h','t','t','p',':','/','/','w','w','w','.','w','3','.','o','r','g',
64 '/','X','M','L','/','1','9','9','8','/','n','a','m','e','s','p','a','c','e',0};
66 typedef struct
68 DispatchEx dispex;
69 IMXNamespaceManager IMXNamespaceManager_iface;
70 IVBMXNamespaceManager IVBMXNamespaceManager_iface;
71 LONG ref;
73 struct list ctxts;
75 VARIANT_BOOL override;
76 } namespacemanager;
78 static inline namespacemanager *impl_from_IMXNamespaceManager( IMXNamespaceManager *iface )
80 return CONTAINING_RECORD(iface, namespacemanager, IMXNamespaceManager_iface);
83 static inline namespacemanager *impl_from_IVBMXNamespaceManager( IVBMXNamespaceManager *iface )
85 return CONTAINING_RECORD(iface, namespacemanager, IVBMXNamespaceManager_iface);
88 static HRESULT declare_prefix(namespacemanager *This, const WCHAR *prefix, const WCHAR *uri)
90 struct nscontext *ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
91 static const WCHAR emptyW[] = {0};
92 struct ns *ns;
93 int i;
95 if (ctxt->count == ctxt->max_alloc)
97 ctxt->max_alloc *= 2;
98 ctxt->ns = heap_realloc(ctxt->ns, ctxt->max_alloc*sizeof(*ctxt->ns));
101 if (!prefix) prefix = emptyW;
103 ns = NULL;
104 for (i = 0; i < ctxt->count; i++)
105 if (!strcmpW(ctxt->ns[i].prefix, prefix))
107 ns = &ctxt->ns[i];
108 break;
111 if (ns)
113 if (This->override == VARIANT_TRUE)
115 SysFreeString(ns->uri);
116 ns->uri = SysAllocString(uri);
117 return S_FALSE;
119 else
120 return E_FAIL;
122 else
124 ctxt->ns[ctxt->count].prefix = SysAllocString(prefix);
125 ctxt->ns[ctxt->count].uri = SysAllocString(uri);
126 ctxt->count++;
129 return S_OK;
132 /* returned stored pointer, caller needs to copy it */
133 static HRESULT get_declared_prefix_idx(const struct nscontext *ctxt, LONG index, BSTR *prefix)
135 *prefix = NULL;
137 if (index >= ctxt->count || index < 0) return E_FAIL;
139 if (index > 0) index = ctxt->count - index;
140 *prefix = ctxt->ns[index].prefix;
142 return S_OK;
145 /* returned stored pointer, caller needs to copy it */
146 static HRESULT get_declared_prefix_uri(const struct list *ctxts, const WCHAR *uri, BSTR *prefix)
148 struct nscontext *ctxt;
150 LIST_FOR_EACH_ENTRY(ctxt, ctxts, struct nscontext, entry)
152 int i;
153 for (i = 0; i < ctxt->count; i++)
154 if (!strcmpW(ctxt->ns[i].uri, uri))
156 *prefix = ctxt->ns[i].prefix;
157 return S_OK;
161 *prefix = NULL;
162 return E_FAIL;
165 static HRESULT get_uri_from_prefix(const struct nscontext *ctxt, const WCHAR *prefix, BSTR *uri)
167 int i;
169 for (i = 0; i < ctxt->count; i++)
170 if (!strcmpW(ctxt->ns[i].prefix, prefix))
172 *uri = ctxt->ns[i].uri;
173 return S_OK;
176 *uri = NULL;
177 return S_FALSE;
180 static struct nscontext* alloc_ns_context(void)
182 struct nscontext *ctxt;
184 ctxt = heap_alloc(sizeof(*ctxt));
185 if (!ctxt) return NULL;
187 ctxt->count = 0;
188 ctxt->max_alloc = DEFAULT_PREFIX_ALLOC_COUNT;
189 ctxt->ns = heap_alloc(ctxt->max_alloc*sizeof(*ctxt->ns));
190 if (!ctxt->ns)
192 heap_free(ctxt);
193 return NULL;
196 /* first allocated prefix is always 'xml' */
197 ctxt->ns[0].prefix = SysAllocString(xmlW);
198 ctxt->ns[0].uri = SysAllocString(xmluriW);
199 ctxt->count++;
200 if (!ctxt->ns[0].prefix || !ctxt->ns[0].uri)
202 heap_free(ctxt->ns);
203 heap_free(ctxt);
204 return NULL;
207 return ctxt;
210 static void free_ns_context(struct nscontext *ctxt)
212 int i;
214 for (i = 0; i < ctxt->count; i++)
216 SysFreeString(ctxt->ns[i].prefix);
217 SysFreeString(ctxt->ns[i].uri);
220 heap_free(ctxt->ns);
221 heap_free(ctxt);
224 static HRESULT WINAPI namespacemanager_QueryInterface(IMXNamespaceManager *iface, REFIID riid, void **ppvObject)
226 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
227 return IVBMXNamespaceManager_QueryInterface(&This->IVBMXNamespaceManager_iface, riid, ppvObject);
230 static ULONG WINAPI namespacemanager_AddRef(IMXNamespaceManager *iface)
232 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
233 return IVBMXNamespaceManager_AddRef(&This->IVBMXNamespaceManager_iface);
236 static ULONG WINAPI namespacemanager_Release(IMXNamespaceManager *iface)
238 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
239 return IVBMXNamespaceManager_Release(&This->IVBMXNamespaceManager_iface);
242 static HRESULT WINAPI namespacemanager_putAllowOverride(IMXNamespaceManager *iface,
243 VARIANT_BOOL override)
245 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
246 return IVBMXNamespaceManager_put_allowOverride(&This->IVBMXNamespaceManager_iface, override);
249 static HRESULT WINAPI namespacemanager_getAllowOverride(IMXNamespaceManager *iface,
250 VARIANT_BOOL *override)
252 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
253 return IVBMXNamespaceManager_get_allowOverride(&This->IVBMXNamespaceManager_iface, override);
256 static HRESULT WINAPI namespacemanager_reset(IMXNamespaceManager *iface)
258 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
259 return IVBMXNamespaceManager_reset(&This->IVBMXNamespaceManager_iface);
262 static HRESULT WINAPI namespacemanager_pushContext(IMXNamespaceManager *iface)
264 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
265 return IVBMXNamespaceManager_pushContext(&This->IVBMXNamespaceManager_iface);
268 static HRESULT WINAPI namespacemanager_pushNodeContext(IMXNamespaceManager *iface,
269 IXMLDOMNode *node, VARIANT_BOOL deep)
271 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
272 return IVBMXNamespaceManager_pushNodeContext(&This->IVBMXNamespaceManager_iface, node, deep);
275 static HRESULT WINAPI namespacemanager_popContext(IMXNamespaceManager *iface)
277 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
278 return IVBMXNamespaceManager_popContext(&This->IVBMXNamespaceManager_iface);
281 static HRESULT WINAPI namespacemanager_declarePrefix(IMXNamespaceManager *iface,
282 const WCHAR *prefix, const WCHAR *namespaceURI)
284 static const WCHAR xmlnsW[] = {'x','m','l','n','s',0};
286 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
288 TRACE("(%p)->(%s %s)\n", This, debugstr_w(prefix), debugstr_w(namespaceURI));
290 if (prefix && (!strcmpW(prefix, xmlW) || !strcmpW(prefix, xmlnsW) || !namespaceURI))
291 return E_INVALIDARG;
293 return declare_prefix(This, prefix, namespaceURI);
296 static HRESULT WINAPI namespacemanager_getDeclaredPrefix(IMXNamespaceManager *iface,
297 LONG index, WCHAR *prefix, int *prefix_len)
299 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
300 struct nscontext *ctxt;
301 HRESULT hr;
302 BSTR prfx;
304 TRACE("(%p)->(%d %p %p)\n", This, index, prefix, prefix_len);
306 if (!prefix_len) return E_POINTER;
308 ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
309 hr = get_declared_prefix_idx(ctxt, index, &prfx);
310 if (hr != S_OK) return hr;
312 if (prefix)
314 if (*prefix_len < (INT)SysStringLen(prfx)) return E_XML_BUFFERTOOSMALL;
315 strcpyW(prefix, prfx);
318 *prefix_len = SysStringLen(prfx);
320 return S_OK;
323 static HRESULT WINAPI namespacemanager_getPrefix(IMXNamespaceManager *iface,
324 const WCHAR *uri, LONG index, WCHAR *prefix, int *prefix_len)
326 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
327 HRESULT hr;
328 BSTR prfx;
330 TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(uri), index, prefix, prefix_len);
332 if (!uri || !*uri || !prefix_len) return E_INVALIDARG;
334 hr = get_declared_prefix_uri(&This->ctxts, uri, &prfx);
335 if (hr == S_OK)
337 /* TODO: figure out what index argument is for */
338 if (index) return E_FAIL;
340 if (prefix)
342 if (*prefix_len < (INT)SysStringLen(prfx)) return E_XML_BUFFERTOOSMALL;
343 strcpyW(prefix, prfx);
346 *prefix_len = SysStringLen(prfx);
347 TRACE("prefix=%s\n", debugstr_w(prfx));
350 return hr;
353 static HRESULT WINAPI namespacemanager_getURI(IMXNamespaceManager *iface,
354 const WCHAR *prefix, IXMLDOMNode *node, WCHAR *uri, int *uri_len)
356 namespacemanager *This = impl_from_IMXNamespaceManager( iface );
357 struct nscontext *ctxt;
358 HRESULT hr;
359 BSTR urib;
361 TRACE("(%p)->(%s %p %p %p)\n", This, debugstr_w(prefix), node, uri, uri_len);
363 if (!prefix) return E_INVALIDARG;
364 if (!uri_len) return E_POINTER;
366 if (node)
368 FIXME("namespaces from DOM node not supported\n");
369 return E_NOTIMPL;
372 ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
373 hr = get_uri_from_prefix(ctxt, prefix, &urib);
374 if (hr == S_OK)
376 if (uri)
378 if (*uri_len < (INT)SysStringLen(urib)) return E_XML_BUFFERTOOSMALL;
379 strcpyW(uri, urib);
382 else
383 if (uri) *uri = 0;
385 *uri_len = SysStringLen(urib);
387 return hr;
390 static const struct IMXNamespaceManagerVtbl MXNamespaceManagerVtbl =
392 namespacemanager_QueryInterface,
393 namespacemanager_AddRef,
394 namespacemanager_Release,
395 namespacemanager_putAllowOverride,
396 namespacemanager_getAllowOverride,
397 namespacemanager_reset,
398 namespacemanager_pushContext,
399 namespacemanager_pushNodeContext,
400 namespacemanager_popContext,
401 namespacemanager_declarePrefix,
402 namespacemanager_getDeclaredPrefix,
403 namespacemanager_getPrefix,
404 namespacemanager_getURI
407 static HRESULT WINAPI vbnamespacemanager_QueryInterface(IVBMXNamespaceManager *iface, REFIID riid, void **obj)
409 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
410 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
412 if ( IsEqualGUID( riid, &IID_IMXNamespaceManager) ||
413 IsEqualGUID( riid, &IID_IUnknown) )
415 *obj = &This->IMXNamespaceManager_iface;
417 else if ( IsEqualGUID( riid, &IID_IVBMXNamespaceManager) ||
418 IsEqualGUID( riid, &IID_IDispatch) )
420 *obj = &This->IVBMXNamespaceManager_iface;
422 else if (dispex_query_interface(&This->dispex, riid, obj))
424 return *obj ? S_OK : E_NOINTERFACE;
426 else
428 TRACE("Unsupported interface %s\n", debugstr_guid(riid));
429 *obj = NULL;
430 return E_NOINTERFACE;
433 IVBMXNamespaceManager_AddRef( iface );
435 return S_OK;
438 static ULONG WINAPI vbnamespacemanager_AddRef(IVBMXNamespaceManager *iface)
440 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
441 ULONG ref = InterlockedIncrement( &This->ref );
442 TRACE("(%p)->(%u)\n", This, ref );
443 return ref;
446 static ULONG WINAPI vbnamespacemanager_Release(IVBMXNamespaceManager *iface)
448 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
449 ULONG ref = InterlockedDecrement( &This->ref );
451 TRACE("(%p)->(%u)\n", This, ref );
453 if ( ref == 0 )
455 struct nscontext *ctxt, *ctxt2;
457 LIST_FOR_EACH_ENTRY_SAFE(ctxt, ctxt2, &This->ctxts, struct nscontext, entry)
459 list_remove(&ctxt->entry);
460 free_ns_context(ctxt);
463 heap_free( This );
466 return ref;
469 static HRESULT WINAPI vbnamespacemanager_GetTypeInfoCount(IVBMXNamespaceManager *iface, UINT *pctinfo)
471 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
472 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
475 static HRESULT WINAPI vbnamespacemanager_GetTypeInfo(IVBMXNamespaceManager *iface, UINT iTInfo,
476 LCID lcid, ITypeInfo **ppTInfo)
478 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
479 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
480 iTInfo, lcid, ppTInfo);
483 static HRESULT WINAPI vbnamespacemanager_GetIDsOfNames(IVBMXNamespaceManager *iface, REFIID riid,
484 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
486 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
487 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
488 riid, rgszNames, cNames, lcid, rgDispId);
491 static HRESULT WINAPI vbnamespacemanager_Invoke(IVBMXNamespaceManager *iface, DISPID dispIdMember, REFIID riid,
492 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
493 EXCEPINFO *pExcepInfo, UINT *puArgErr)
495 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
496 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
497 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
500 static HRESULT WINAPI vbnamespacemanager_put_allowOverride(IVBMXNamespaceManager *iface,
501 VARIANT_BOOL override)
503 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
505 TRACE("(%p)->(%d)\n", This, override);
506 This->override = override;
508 return S_OK;
511 static HRESULT WINAPI vbnamespacemanager_get_allowOverride(IVBMXNamespaceManager *iface,
512 VARIANT_BOOL *override)
514 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
516 TRACE("(%p)->(%p)\n", This, override);
518 if (!override) return E_POINTER;
519 *override = This->override;
521 return S_OK;
524 static HRESULT WINAPI vbnamespacemanager_reset(IVBMXNamespaceManager *iface)
526 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
527 FIXME("(%p): stub\n", This);
528 return E_NOTIMPL;
531 static HRESULT WINAPI vbnamespacemanager_pushContext(IVBMXNamespaceManager *iface)
533 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
534 struct nscontext *ctxt;
536 TRACE("(%p)\n", This);
538 ctxt = alloc_ns_context();
539 if (!ctxt) return E_OUTOFMEMORY;
541 list_add_head(&This->ctxts, &ctxt->entry);
543 return S_OK;
546 static HRESULT WINAPI vbnamespacemanager_pushNodeContext(IVBMXNamespaceManager *iface,
547 IXMLDOMNode *node, VARIANT_BOOL deep)
549 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
550 FIXME("(%p)->(%p %d): stub\n", This, node, deep);
551 return E_NOTIMPL;
554 static HRESULT WINAPI vbnamespacemanager_popContext(IVBMXNamespaceManager *iface)
556 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
557 const struct list *next;
558 struct nscontext *ctxt;
560 TRACE("(%p)\n", This);
562 next = list_next(&This->ctxts, list_head(&This->ctxts));
563 if (!next) return E_FAIL;
565 ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
566 list_remove(list_head(&This->ctxts));
568 free_ns_context(ctxt);
570 return S_OK;
573 static HRESULT WINAPI vbnamespacemanager_declarePrefix(IVBMXNamespaceManager *iface,
574 BSTR prefix, BSTR namespaceURI)
576 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
577 return IMXNamespaceManager_declarePrefix(&This->IMXNamespaceManager_iface, prefix, namespaceURI);
580 static HRESULT WINAPI vbnamespacemanager_getDeclaredPrefixes(IVBMXNamespaceManager *iface,
581 IMXNamespacePrefixes** prefixes)
583 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
584 FIXME("(%p)->(%p): stub\n", This, prefixes);
585 return E_NOTIMPL;
588 static HRESULT WINAPI vbnamespacemanager_getPrefixes(IVBMXNamespaceManager *iface,
589 BSTR namespaceURI, IMXNamespacePrefixes** prefixes)
591 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
592 FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(namespaceURI), prefixes);
593 return E_NOTIMPL;
596 static HRESULT WINAPI vbnamespacemanager_getURI(IVBMXNamespaceManager *iface,
597 BSTR prefix, VARIANT* uri)
599 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
600 FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(prefix), uri);
601 return E_NOTIMPL;
604 static HRESULT WINAPI vbnamespacemanager_getURIFromNode(IVBMXNamespaceManager *iface,
605 BSTR prefix, IXMLDOMNode *node, VARIANT *uri)
607 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
608 FIXME("(%p)->(%s %p %p): stub\n", This, debugstr_w(prefix), node, uri);
609 return E_NOTIMPL;
612 static const struct IVBMXNamespaceManagerVtbl VBMXNamespaceManagerVtbl =
614 vbnamespacemanager_QueryInterface,
615 vbnamespacemanager_AddRef,
616 vbnamespacemanager_Release,
617 vbnamespacemanager_GetTypeInfoCount,
618 vbnamespacemanager_GetTypeInfo,
619 vbnamespacemanager_GetIDsOfNames,
620 vbnamespacemanager_Invoke,
621 vbnamespacemanager_put_allowOverride,
622 vbnamespacemanager_get_allowOverride,
623 vbnamespacemanager_reset,
624 vbnamespacemanager_pushContext,
625 vbnamespacemanager_pushNodeContext,
626 vbnamespacemanager_popContext,
627 vbnamespacemanager_declarePrefix,
628 vbnamespacemanager_getDeclaredPrefixes,
629 vbnamespacemanager_getPrefixes,
630 vbnamespacemanager_getURI,
631 vbnamespacemanager_getURIFromNode
634 static const tid_t namespacemanager_iface_tids[] = {
635 IVBMXNamespaceManager_tid,
639 static dispex_static_data_t namespacemanager_dispex = {
640 NULL,
641 IVBMXNamespaceManager_tid,
642 NULL,
643 namespacemanager_iface_tids
646 HRESULT MXNamespaceManager_create(void **obj)
648 namespacemanager *This;
649 struct nscontext *ctxt;
651 TRACE("(%p)\n", obj);
653 This = heap_alloc( sizeof (*This) );
654 if( !This )
655 return E_OUTOFMEMORY;
657 This->IMXNamespaceManager_iface.lpVtbl = &MXNamespaceManagerVtbl;
658 This->IVBMXNamespaceManager_iface.lpVtbl = &VBMXNamespaceManagerVtbl;
659 This->ref = 1;
660 init_dispex(&This->dispex, (IUnknown*)&This->IVBMXNamespaceManager_iface, &namespacemanager_dispex);
662 list_init(&This->ctxts);
663 ctxt = alloc_ns_context();
664 if (!ctxt)
666 heap_free(This);
667 return E_OUTOFMEMORY;
670 list_add_head(&This->ctxts, &ctxt->entry);
672 This->override = VARIANT_TRUE;
674 *obj = &This->IMXNamespaceManager_iface;
676 TRACE("returning iface %p\n", *obj);
678 return S_OK;