2 * IMXNamespaceManager implementation
4 * Copyright 2011 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
22 #define NONAMELESSUNION
28 # include <libxml/parser.h>
29 # include <libxml/xmlerror.h>
30 # include <libxml/encoding.h>
39 #include "msxml_private.h"
41 #include "wine/debug.h"
42 #include "wine/list.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
61 #define DEFAULT_PREFIX_ALLOC_COUNT 16
63 static const WCHAR xmlW
[] = {'x','m','l',0};
64 static const WCHAR xmluriW
[] = {'h','t','t','p',':','/','/','w','w','w','.','w','3','.','o','r','g',
65 '/','X','M','L','/','1','9','9','8','/','n','a','m','e','s','p','a','c','e',0};
69 IMXNamespaceManager IMXNamespaceManager_iface
;
70 IVBMXNamespaceManager IVBMXNamespaceManager_iface
;
75 VARIANT_BOOL override
;
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};
95 if (ctxt
->count
== ctxt
->max_alloc
)
98 ctxt
->ns
= heap_realloc(ctxt
->ns
, ctxt
->max_alloc
*sizeof(*ctxt
->ns
));
101 if (!prefix
) prefix
= emptyW
;
104 for (i
= 0; i
< ctxt
->count
; i
++)
105 if (!strcmpW(ctxt
->ns
[i
].prefix
, prefix
))
113 if (This
->override
== VARIANT_TRUE
)
115 SysFreeString(ns
->uri
);
116 ns
->uri
= SysAllocString(uri
);
124 ctxt
->ns
[ctxt
->count
].prefix
= SysAllocString(prefix
);
125 ctxt
->ns
[ctxt
->count
].uri
= SysAllocString(uri
);
132 /* returned stored pointer, caller needs to copy it */
133 static HRESULT
get_declared_prefix_idx(const struct nscontext
*ctxt
, LONG index
, BSTR
*prefix
)
137 if (index
>= ctxt
->count
|| index
< 0) return E_FAIL
;
139 if (index
> 0) index
= ctxt
->count
- index
;
140 *prefix
= ctxt
->ns
[index
].prefix
;
145 static HRESULT
get_uri_from_prefix(const struct nscontext
*ctxt
, const WCHAR
*prefix
, BSTR
*uri
)
149 for (i
= 0; i
< ctxt
->count
; i
++)
150 if (!strcmpW(ctxt
->ns
[i
].prefix
, prefix
))
152 *uri
= ctxt
->ns
[i
].uri
;
160 static struct nscontext
* alloc_ns_context(void)
162 struct nscontext
*ctxt
;
164 ctxt
= heap_alloc(sizeof(*ctxt
));
165 if (!ctxt
) return NULL
;
168 ctxt
->max_alloc
= DEFAULT_PREFIX_ALLOC_COUNT
;
169 ctxt
->ns
= heap_alloc(ctxt
->max_alloc
*sizeof(*ctxt
->ns
));
171 /* first allocated prefix is always 'xml' */
172 ctxt
->ns
[0].prefix
= SysAllocString(xmlW
);
173 ctxt
->ns
[0].uri
= SysAllocString(xmluriW
);
179 static void free_ns_context(struct nscontext
*ctxt
)
183 for (i
= 0; i
< ctxt
->count
; i
++)
185 SysFreeString(ctxt
->ns
[i
].prefix
);
186 SysFreeString(ctxt
->ns
[i
].uri
);
193 static HRESULT WINAPI
namespacemanager_QueryInterface(IMXNamespaceManager
*iface
, REFIID riid
, void **ppvObject
)
195 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
196 return IVBMXNamespaceManager_QueryInterface(&This
->IVBMXNamespaceManager_iface
, riid
, ppvObject
);
199 static ULONG WINAPI
namespacemanager_AddRef(IMXNamespaceManager
*iface
)
201 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
202 return IVBMXNamespaceManager_AddRef(&This
->IVBMXNamespaceManager_iface
);
205 static ULONG WINAPI
namespacemanager_Release(IMXNamespaceManager
*iface
)
207 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
208 return IVBMXNamespaceManager_Release(&This
->IVBMXNamespaceManager_iface
);
211 static HRESULT WINAPI
namespacemanager_putAllowOverride(IMXNamespaceManager
*iface
,
212 VARIANT_BOOL override
)
214 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
215 return IVBMXNamespaceManager_put_allowOverride(&This
->IVBMXNamespaceManager_iface
, override
);
218 static HRESULT WINAPI
namespacemanager_getAllowOverride(IMXNamespaceManager
*iface
,
219 VARIANT_BOOL
*override
)
221 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
222 return IVBMXNamespaceManager_get_allowOverride(&This
->IVBMXNamespaceManager_iface
, override
);
225 static HRESULT WINAPI
namespacemanager_reset(IMXNamespaceManager
*iface
)
227 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
228 return IVBMXNamespaceManager_reset(&This
->IVBMXNamespaceManager_iface
);
231 static HRESULT WINAPI
namespacemanager_pushContext(IMXNamespaceManager
*iface
)
233 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
234 return IVBMXNamespaceManager_pushContext(&This
->IVBMXNamespaceManager_iface
);
237 static HRESULT WINAPI
namespacemanager_pushNodeContext(IMXNamespaceManager
*iface
,
238 IXMLDOMNode
*node
, VARIANT_BOOL deep
)
240 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
241 return IVBMXNamespaceManager_pushNodeContext(&This
->IVBMXNamespaceManager_iface
, node
, deep
);
244 static HRESULT WINAPI
namespacemanager_popContext(IMXNamespaceManager
*iface
)
246 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
247 return IVBMXNamespaceManager_popContext(&This
->IVBMXNamespaceManager_iface
);
250 static HRESULT WINAPI
namespacemanager_declarePrefix(IMXNamespaceManager
*iface
,
251 const WCHAR
*prefix
, const WCHAR
*namespaceURI
)
253 static const WCHAR xmlnsW
[] = {'x','m','l','n','s',0};
255 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
257 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(prefix
), debugstr_w(namespaceURI
));
259 if (prefix
&& (!strcmpW(prefix
, xmlW
) || !strcmpW(prefix
, xmlnsW
) || !namespaceURI
))
262 return declare_prefix(This
, prefix
, namespaceURI
);
265 static HRESULT WINAPI
namespacemanager_getDeclaredPrefix(IMXNamespaceManager
*iface
,
266 LONG index
, WCHAR
*prefix
, int *prefix_len
)
268 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
269 struct nscontext
*ctxt
;
273 TRACE("(%p)->(%d %p %p)\n", This
, index
, prefix
, prefix_len
);
275 if (!prefix_len
) return E_POINTER
;
277 ctxt
= LIST_ENTRY(list_head(&This
->ctxts
), struct nscontext
, entry
);
278 hr
= get_declared_prefix_idx(ctxt
, index
, &prfx
);
279 if (hr
!= S_OK
) return hr
;
283 if (*prefix_len
< (INT
)SysStringLen(prfx
)) return E_XML_BUFFERTOOSMALL
;
284 strcpyW(prefix
, prfx
);
287 *prefix_len
= SysStringLen(prfx
);
292 static HRESULT WINAPI
namespacemanager_getPrefix(IMXNamespaceManager
*iface
,
293 const WCHAR
*uri
, LONG index
, WCHAR
*prefix
, int *prefix_len
)
295 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
296 FIXME("(%p)->(%s %d %p %p): stub\n", This
, debugstr_w(uri
), index
, prefix
, prefix_len
);
300 static HRESULT WINAPI
namespacemanager_getURI(IMXNamespaceManager
*iface
,
301 const WCHAR
*prefix
, IXMLDOMNode
*node
, WCHAR
*uri
, int *uri_len
)
303 namespacemanager
*This
= impl_from_IMXNamespaceManager( iface
);
304 struct nscontext
*ctxt
;
308 TRACE("(%p)->(%s %p %p %p)\n", This
, debugstr_w(prefix
), node
, uri
, uri_len
);
310 if (!prefix
) return E_INVALIDARG
;
311 if (!uri_len
) return E_POINTER
;
315 FIXME("namespaces from DOM node not supported\n");
319 ctxt
= LIST_ENTRY(list_head(&This
->ctxts
), struct nscontext
, entry
);
320 hr
= get_uri_from_prefix(ctxt
, prefix
, &urib
);
325 if (*uri_len
< (INT
)SysStringLen(urib
)) return E_XML_BUFFERTOOSMALL
;
332 *uri_len
= SysStringLen(urib
);
337 static const struct IMXNamespaceManagerVtbl MXNamespaceManagerVtbl
=
339 namespacemanager_QueryInterface
,
340 namespacemanager_AddRef
,
341 namespacemanager_Release
,
342 namespacemanager_putAllowOverride
,
343 namespacemanager_getAllowOverride
,
344 namespacemanager_reset
,
345 namespacemanager_pushContext
,
346 namespacemanager_pushNodeContext
,
347 namespacemanager_popContext
,
348 namespacemanager_declarePrefix
,
349 namespacemanager_getDeclaredPrefix
,
350 namespacemanager_getPrefix
,
351 namespacemanager_getURI
354 static HRESULT WINAPI
vbnamespacemanager_QueryInterface(IVBMXNamespaceManager
*iface
, REFIID riid
, void **ppvObject
)
356 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
357 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
359 if ( IsEqualGUID( riid
, &IID_IMXNamespaceManager
) ||
360 IsEqualGUID( riid
, &IID_IUnknown
) )
362 *ppvObject
= &This
->IMXNamespaceManager_iface
;
364 else if ( IsEqualGUID( riid
, &IID_IVBMXNamespaceManager
) ||
365 IsEqualGUID( riid
, &IID_IDispatch
) )
367 *ppvObject
= &This
->IVBMXNamespaceManager_iface
;
371 TRACE("Unsupported interface %s\n", debugstr_guid(riid
));
373 return E_NOINTERFACE
;
376 IVBMXNamespaceManager_AddRef( iface
);
381 static ULONG WINAPI
vbnamespacemanager_AddRef(IVBMXNamespaceManager
*iface
)
383 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
384 ULONG ref
= InterlockedIncrement( &This
->ref
);
385 TRACE("(%p)->(%u)\n", This
, ref
);
389 static ULONG WINAPI
vbnamespacemanager_Release(IVBMXNamespaceManager
*iface
)
391 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
392 ULONG ref
= InterlockedDecrement( &This
->ref
);
394 TRACE("(%p)->(%u)\n", This
, ref
);
398 struct nscontext
*ctxt
, *ctxt2
;
400 LIST_FOR_EACH_ENTRY_SAFE(ctxt
, ctxt2
, &This
->ctxts
, struct nscontext
, entry
)
402 list_remove(&ctxt
->entry
);
403 free_ns_context(ctxt
);
412 static HRESULT WINAPI
vbnamespacemanager_GetTypeInfoCount(IVBMXNamespaceManager
*iface
, UINT
*pctinfo
)
414 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
416 TRACE("(%p)->(%p)\n", This
, pctinfo
);
422 static HRESULT WINAPI
vbnamespacemanager_GetTypeInfo(IVBMXNamespaceManager
*iface
, UINT iTInfo
,
423 LCID lcid
, ITypeInfo
**ppTInfo
)
425 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
427 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
429 return get_typeinfo(IVBMXNamespaceManager_tid
, ppTInfo
);
432 static HRESULT WINAPI
vbnamespacemanager_GetIDsOfNames(IVBMXNamespaceManager
*iface
, REFIID riid
,
433 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
435 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
439 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
442 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
445 hr
= get_typeinfo(IVBMXNamespaceManager_tid
, &typeinfo
);
448 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
449 ITypeInfo_Release(typeinfo
);
455 static HRESULT WINAPI
vbnamespacemanager_Invoke(IVBMXNamespaceManager
*iface
, DISPID dispIdMember
, REFIID riid
,
456 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
457 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
459 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
463 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
464 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
466 hr
= get_typeinfo(IVBMXNamespaceManager_tid
, &typeinfo
);
469 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IVBMXNamespaceManager_iface
, dispIdMember
, wFlags
,
470 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
471 ITypeInfo_Release(typeinfo
);
477 static HRESULT WINAPI
vbnamespacemanager_put_allowOverride(IVBMXNamespaceManager
*iface
,
478 VARIANT_BOOL override
)
480 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
482 TRACE("(%p)->(%d)\n", This
, override
);
483 This
->override
= override
;
488 static HRESULT WINAPI
vbnamespacemanager_get_allowOverride(IVBMXNamespaceManager
*iface
,
489 VARIANT_BOOL
*override
)
491 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
493 TRACE("(%p)->(%p)\n", This
, override
);
495 if (!override
) return E_POINTER
;
496 *override
= This
->override
;
501 static HRESULT WINAPI
vbnamespacemanager_reset(IVBMXNamespaceManager
*iface
)
503 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
504 FIXME("(%p): stub\n", This
);
508 static HRESULT WINAPI
vbnamespacemanager_pushContext(IVBMXNamespaceManager
*iface
)
510 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
511 FIXME("(%p): stub\n", This
);
515 static HRESULT WINAPI
vbnamespacemanager_pushNodeContext(IVBMXNamespaceManager
*iface
,
516 IXMLDOMNode
*node
, VARIANT_BOOL deep
)
518 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
519 FIXME("(%p)->(%p %d): stub\n", This
, node
, deep
);
523 static HRESULT WINAPI
vbnamespacemanager_popContext(IVBMXNamespaceManager
*iface
)
525 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
526 FIXME("(%p): stub\n", This
);
530 static HRESULT WINAPI
vbnamespacemanager_declarePrefix(IVBMXNamespaceManager
*iface
,
531 BSTR prefix
, BSTR namespaceURI
)
533 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
534 return IMXNamespaceManager_declarePrefix(&This
->IMXNamespaceManager_iface
, prefix
, namespaceURI
);
537 static HRESULT WINAPI
vbnamespacemanager_getDeclaredPrefixes(IVBMXNamespaceManager
*iface
,
538 IMXNamespacePrefixes
** prefixes
)
540 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
541 FIXME("(%p)->(%p): stub\n", This
, prefixes
);
545 static HRESULT WINAPI
vbnamespacemanager_getPrefixes(IVBMXNamespaceManager
*iface
,
546 BSTR namespaceURI
, IMXNamespacePrefixes
** prefixes
)
548 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
549 FIXME("(%p)->(%s %p): stub\n", This
, debugstr_w(namespaceURI
), prefixes
);
553 static HRESULT WINAPI
vbnamespacemanager_getURI(IVBMXNamespaceManager
*iface
,
554 BSTR prefix
, VARIANT
* uri
)
556 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
557 FIXME("(%p)->(%s %p): stub\n", This
, debugstr_w(prefix
), uri
);
561 static HRESULT WINAPI
vbnamespacemanager_getURIFromNode(IVBMXNamespaceManager
*iface
,
562 BSTR prefix
, IXMLDOMNode
*node
, VARIANT
*uri
)
564 namespacemanager
*This
= impl_from_IVBMXNamespaceManager( iface
);
565 FIXME("(%p)->(%s %p %p): stub\n", This
, debugstr_w(prefix
), node
, uri
);
569 static const struct IVBMXNamespaceManagerVtbl VBMXNamespaceManagerVtbl
=
571 vbnamespacemanager_QueryInterface
,
572 vbnamespacemanager_AddRef
,
573 vbnamespacemanager_Release
,
574 vbnamespacemanager_GetTypeInfoCount
,
575 vbnamespacemanager_GetTypeInfo
,
576 vbnamespacemanager_GetIDsOfNames
,
577 vbnamespacemanager_Invoke
,
578 vbnamespacemanager_put_allowOverride
,
579 vbnamespacemanager_get_allowOverride
,
580 vbnamespacemanager_reset
,
581 vbnamespacemanager_pushContext
,
582 vbnamespacemanager_pushNodeContext
,
583 vbnamespacemanager_popContext
,
584 vbnamespacemanager_declarePrefix
,
585 vbnamespacemanager_getDeclaredPrefixes
,
586 vbnamespacemanager_getPrefixes
,
587 vbnamespacemanager_getURI
,
588 vbnamespacemanager_getURIFromNode
591 HRESULT
MXNamespaceManager_create(IUnknown
*outer
, void **obj
)
593 namespacemanager
*ns
;
594 struct nscontext
*ctxt
;
596 TRACE("(%p, %p)\n", outer
, obj
);
598 ns
= heap_alloc( sizeof (*ns
) );
600 return E_OUTOFMEMORY
;
602 ns
->IMXNamespaceManager_iface
.lpVtbl
= &MXNamespaceManagerVtbl
;
603 ns
->IVBMXNamespaceManager_iface
.lpVtbl
= &VBMXNamespaceManagerVtbl
;
606 list_init(&ns
->ctxts
);
607 ctxt
= alloc_ns_context();
608 list_add_head(&ns
->ctxts
, &ctxt
->entry
);
610 ns
->override
= VARIANT_TRUE
;
612 *obj
= &ns
->IMXNamespaceManager_iface
;
614 TRACE("returning iface %p\n", *obj
);