2 * Node map implementation
4 * Copyright 2005 Mike McCormack
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
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
38 #include "msxml_private.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
46 typedef struct _xmlnodemap
48 IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface
;
49 ISupportErrorInfo ISupportErrorInfo_iface
;
56 static inline xmlnodemap
*impl_from_IXMLDOMNamedNodeMap( IXMLDOMNamedNodeMap
*iface
)
58 return CONTAINING_RECORD(iface
, xmlnodemap
, IXMLDOMNamedNodeMap_iface
);
61 static inline xmlnodemap
*impl_from_ISupportErrorInfo( ISupportErrorInfo
*iface
)
63 return CONTAINING_RECORD(iface
, xmlnodemap
, ISupportErrorInfo_iface
);
66 static HRESULT WINAPI
xmlnodemap_QueryInterface(
67 IXMLDOMNamedNodeMap
*iface
,
68 REFIID riid
, void** ppvObject
)
70 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
71 TRACE("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppvObject
);
73 if( IsEqualGUID( riid
, &IID_IUnknown
) ||
74 IsEqualGUID( riid
, &IID_IDispatch
) ||
75 IsEqualGUID( riid
, &IID_IXMLDOMNamedNodeMap
) )
79 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
81 *ppvObject
= &This
->ISupportErrorInfo_iface
;
85 TRACE("interface %s not implemented\n", debugstr_guid(riid
));
90 IXMLDOMElement_AddRef( iface
);
95 static ULONG WINAPI
xmlnodemap_AddRef(
96 IXMLDOMNamedNodeMap
*iface
)
98 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
99 ULONG ref
= InterlockedIncrement( &This
->ref
);
100 TRACE("(%p)->(%d)\n", This
, ref
);
104 static ULONG WINAPI
xmlnodemap_Release(
105 IXMLDOMNamedNodeMap
*iface
)
107 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
108 ULONG ref
= InterlockedDecrement( &This
->ref
);
110 TRACE("(%p)->(%d)\n", This
, ref
);
113 xmldoc_release( This
->node
->doc
);
120 static HRESULT WINAPI
xmlnodemap_GetTypeInfoCount(
121 IXMLDOMNamedNodeMap
*iface
,
124 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
126 TRACE("(%p)->(%p)\n", This
, pctinfo
);
133 static HRESULT WINAPI
xmlnodemap_GetTypeInfo(
134 IXMLDOMNamedNodeMap
*iface
,
135 UINT iTInfo
, LCID lcid
,
136 ITypeInfo
** ppTInfo
)
138 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
139 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
140 return get_typeinfo(IXMLDOMNamedNodeMap_tid
, ppTInfo
);
143 static HRESULT WINAPI
xmlnodemap_GetIDsOfNames(
144 IXMLDOMNamedNodeMap
*iface
,
145 REFIID riid
, LPOLESTR
* rgszNames
,
146 UINT cNames
, LCID lcid
, DISPID
* rgDispId
)
148 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
152 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
155 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
158 hr
= get_typeinfo(IXMLDOMNamedNodeMap_tid
, &typeinfo
);
161 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
162 ITypeInfo_Release(typeinfo
);
168 static HRESULT WINAPI
xmlnodemap_Invoke(
169 IXMLDOMNamedNodeMap
*iface
,
170 DISPID dispIdMember
, REFIID riid
, LCID lcid
,
171 WORD wFlags
, DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
172 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
174 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
178 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
179 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
181 hr
= get_typeinfo(IXMLDOMNamedNodeMap_tid
, &typeinfo
);
184 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IXMLDOMNamedNodeMap_iface
, dispIdMember
, wFlags
,
185 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
186 ITypeInfo_Release(typeinfo
);
192 static HRESULT WINAPI
xmlnodemap_getNamedItem(
193 IXMLDOMNamedNodeMap
*iface
,
195 IXMLDOMNode
** namedItem
)
197 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
198 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), namedItem
);
199 return IXMLDOMNamedNodeMap_getQualifiedItem(iface
, name
, NULL
, namedItem
);
202 static HRESULT WINAPI
xmlnodemap_setNamedItem(
203 IXMLDOMNamedNodeMap
*iface
,
204 IXMLDOMNode
* newItem
,
205 IXMLDOMNode
** namedItem
)
207 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
211 TRACE("(%p)->(%p %p)\n", This
, newItem
, namedItem
);
216 if(namedItem
) *namedItem
= NULL
;
218 /* Must be an Attribute */
219 ThisNew
= get_node_obj( newItem
);
220 if(!ThisNew
) return E_FAIL
;
222 if(ThisNew
->node
->type
!= XML_ATTRIBUTE_NODE
)
225 if(!ThisNew
->node
->parent
)
226 if(xmldoc_remove_orphan(ThisNew
->node
->doc
, ThisNew
->node
) != S_OK
)
227 WARN("%p is not an orphan of %p\n", ThisNew
->node
, ThisNew
->node
->doc
);
229 nodeNew
= xmlAddChild(This
->node
, ThisNew
->node
);
232 *namedItem
= create_node( nodeNew
);
236 static HRESULT WINAPI
xmlnodemap_removeNamedItem(
237 IXMLDOMNamedNodeMap
*iface
,
239 IXMLDOMNode
** namedItem
)
241 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
242 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), namedItem
);
243 return IXMLDOMNamedNodeMap_removeQualifiedItem(iface
, name
, NULL
, namedItem
);
246 static HRESULT WINAPI
xmlnodemap_get_item(
247 IXMLDOMNamedNodeMap
*iface
,
249 IXMLDOMNode
** listItem
)
251 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
255 TRACE("(%p)->(%d %p)\n", This
, index
, listItem
);
262 curr
= This
->node
->properties
;
264 for (attrIndex
= 0; attrIndex
< index
; attrIndex
++) {
265 if (curr
->next
== NULL
)
271 *listItem
= create_node( (xmlNodePtr
) curr
);
276 static HRESULT WINAPI
xmlnodemap_get_length(
277 IXMLDOMNamedNodeMap
*iface
,
284 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
286 TRACE("(%p)->(%p)\n", This
, listLength
);
291 first
= This
->node
->properties
;
303 *listLength
= attrCount
;
308 static HRESULT WINAPI
xmlnodemap_getQualifiedItem(
309 IXMLDOMNamedNodeMap
*iface
,
312 IXMLDOMNode
** qualifiedItem
)
314 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
319 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(baseName
), debugstr_w(namespaceURI
), qualifiedItem
);
321 if (!baseName
|| !qualifiedItem
) return E_INVALIDARG
;
323 if (namespaceURI
&& *namespaceURI
)
325 href
= xmlchar_from_wchar(namespaceURI
);
326 if (!href
) return E_OUTOFMEMORY
;
331 name
= xmlchar_from_wchar(baseName
);
335 return E_OUTOFMEMORY
;
338 attr
= xmlHasNsProp(This
->node
, name
, href
);
345 *qualifiedItem
= NULL
;
349 *qualifiedItem
= create_node((xmlNodePtr
)attr
);
354 static HRESULT WINAPI
xmlnodemap_removeQualifiedItem(
355 IXMLDOMNamedNodeMap
*iface
,
358 IXMLDOMNode
** qualifiedItem
)
360 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
365 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(baseName
), debugstr_w(namespaceURI
), qualifiedItem
);
367 if (!baseName
) return E_INVALIDARG
;
369 if (namespaceURI
&& *namespaceURI
)
371 href
= xmlchar_from_wchar(namespaceURI
);
372 if (!href
) return E_OUTOFMEMORY
;
377 name
= xmlchar_from_wchar(baseName
);
381 return E_OUTOFMEMORY
;
384 attr
= xmlHasNsProp( This
->node
, name
, href
);
391 if (qualifiedItem
) *qualifiedItem
= NULL
;
397 xmlUnlinkNode( (xmlNodePtr
) attr
);
398 xmldoc_add_orphan( attr
->doc
, (xmlNodePtr
) attr
);
399 *qualifiedItem
= create_node( (xmlNodePtr
) attr
);
403 if (xmlRemoveProp(attr
) == -1)
404 ERR("xmlRemoveProp failed\n");
410 static HRESULT WINAPI
xmlnodemap_nextNode(
411 IXMLDOMNamedNodeMap
*iface
,
412 IXMLDOMNode
** nextItem
)
414 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
418 TRACE("(%p)->(%p: %d)\n", This
, nextItem
, This
->iterator
);
422 curr
= This
->node
->properties
;
424 for (attrIndex
= 0; attrIndex
< This
->iterator
; attrIndex
++) {
425 if (curr
->next
== NULL
)
433 *nextItem
= create_node( (xmlNodePtr
) curr
);
438 static HRESULT WINAPI
xmlnodemap_reset(
439 IXMLDOMNamedNodeMap
*iface
)
441 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
443 TRACE("(%p: %d)\n", This
, This
->iterator
);
450 static HRESULT WINAPI
xmlnodemap__newEnum(
451 IXMLDOMNamedNodeMap
*iface
,
454 xmlnodemap
*This
= impl_from_IXMLDOMNamedNodeMap( iface
);
455 FIXME("(%p)->(%p)\n", This
, ppUnk
);
459 static const struct IXMLDOMNamedNodeMapVtbl xmlnodemap_vtbl
=
461 xmlnodemap_QueryInterface
,
464 xmlnodemap_GetTypeInfoCount
,
465 xmlnodemap_GetTypeInfo
,
466 xmlnodemap_GetIDsOfNames
,
468 xmlnodemap_getNamedItem
,
469 xmlnodemap_setNamedItem
,
470 xmlnodemap_removeNamedItem
,
472 xmlnodemap_get_length
,
473 xmlnodemap_getQualifiedItem
,
474 xmlnodemap_removeQualifiedItem
,
480 static HRESULT WINAPI
support_error_QueryInterface(
481 ISupportErrorInfo
*iface
,
482 REFIID riid
, void** ppvObject
)
484 xmlnodemap
*This
= impl_from_ISupportErrorInfo( iface
);
485 TRACE("%p %s %p\n", iface
, debugstr_guid(riid
), ppvObject
);
486 return IXMLDOMNamedNodeMap_QueryInterface(&This
->IXMLDOMNamedNodeMap_iface
, riid
, ppvObject
);
489 static ULONG WINAPI
support_error_AddRef(
490 ISupportErrorInfo
*iface
)
492 xmlnodemap
*This
= impl_from_ISupportErrorInfo( iface
);
493 return IXMLDOMNamedNodeMap_AddRef(&This
->IXMLDOMNamedNodeMap_iface
);
496 static ULONG WINAPI
support_error_Release(
497 ISupportErrorInfo
*iface
)
499 xmlnodemap
*This
= impl_from_ISupportErrorInfo( iface
);
500 return IXMLDOMNamedNodeMap_Release(&This
->IXMLDOMNamedNodeMap_iface
);
503 static HRESULT WINAPI
support_error_InterfaceSupportsErrorInfo(
504 ISupportErrorInfo
*iface
,
507 FIXME("(%p)->(%s)\n", iface
, debugstr_guid(riid
));
511 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
513 support_error_QueryInterface
,
514 support_error_AddRef
,
515 support_error_Release
,
516 support_error_InterfaceSupportsErrorInfo
519 IXMLDOMNamedNodeMap
*create_nodemap( const xmlNodePtr node
)
523 nodemap
= heap_alloc( sizeof *nodemap
);
527 nodemap
->IXMLDOMNamedNodeMap_iface
.lpVtbl
= &xmlnodemap_vtbl
;
528 nodemap
->ISupportErrorInfo_iface
.lpVtbl
= &support_error_vtbl
;
529 nodemap
->node
= node
;
531 nodemap
->iterator
= 0;
533 xmldoc_add_ref(node
->doc
);
535 return &nodemap
->IXMLDOMNamedNodeMap_iface
;