2 * Node list 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
32 #include "msxml_private.h"
34 #include "wine/debug.h"
36 /* This file implements the object returned by childNodes property. Note that this is
37 * not the IXMLDOMNodeList returned by XPath querites - it's implemented in queryresult.c.
38 * They are different because the list returned by childNodes:
39 * - is "live" - changes to the XML tree are automatically reflected in the list
40 * - doesn't supports IXMLDOMSelection
41 * - note that an attribute node have a text child in DOM but not in the XPath data model
42 * thus the child is inaccessible by an XPath query
45 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
49 typedef struct _xmlnodelist
51 const struct IXMLDOMNodeListVtbl
*lpVtbl
;
57 static inline xmlnodelist
*impl_from_IXMLDOMNodeList( IXMLDOMNodeList
*iface
)
59 return (xmlnodelist
*)((char*)iface
- FIELD_OFFSET(xmlnodelist
, lpVtbl
));
62 static HRESULT WINAPI
xmlnodelist_QueryInterface(
63 IXMLDOMNodeList
*iface
,
67 TRACE("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppvObject
);
72 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
73 IsEqualGUID( riid
, &IID_IDispatch
) ||
74 IsEqualGUID( riid
, &IID_IXMLDOMNodeList
) )
80 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
85 IXMLDOMNodeList_AddRef( iface
);
90 static ULONG WINAPI
xmlnodelist_AddRef(
91 IXMLDOMNodeList
*iface
)
93 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
94 return InterlockedIncrement( &This
->ref
);
97 static ULONG WINAPI
xmlnodelist_Release(
98 IXMLDOMNodeList
*iface
)
100 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
103 ref
= InterlockedDecrement( &This
->ref
);
106 xmldoc_release( This
->parent
->doc
);
113 static HRESULT WINAPI
xmlnodelist_GetTypeInfoCount(
114 IXMLDOMNodeList
*iface
,
117 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
119 TRACE("(%p)->(%p)\n", This
, pctinfo
);
126 static HRESULT WINAPI
xmlnodelist_GetTypeInfo(
127 IXMLDOMNodeList
*iface
,
130 ITypeInfo
** ppTInfo
)
132 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
135 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
137 hr
= get_typeinfo(IXMLDOMNodeList_tid
, ppTInfo
);
142 static HRESULT WINAPI
xmlnodelist_GetIDsOfNames(
143 IXMLDOMNodeList
*iface
,
150 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
154 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
157 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
160 hr
= get_typeinfo(IXMLDOMNodeList_tid
, &typeinfo
);
163 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
164 ITypeInfo_Release(typeinfo
);
170 static HRESULT WINAPI
xmlnodelist_Invoke(
171 IXMLDOMNodeList
*iface
,
176 DISPPARAMS
* pDispParams
,
178 EXCEPINFO
* pExcepInfo
,
181 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
185 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
186 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
188 hr
= get_typeinfo(IXMLDOMNodeList_tid
, &typeinfo
);
191 hr
= ITypeInfo_Invoke(typeinfo
, &(This
->lpVtbl
), dispIdMember
, wFlags
, pDispParams
,
192 pVarResult
, pExcepInfo
, puArgErr
);
193 ITypeInfo_Release(typeinfo
);
199 static HRESULT WINAPI
xmlnodelist_get_item(
200 IXMLDOMNodeList
* iface
,
202 IXMLDOMNode
** listItem
)
204 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
208 TRACE("(%p)->(%d %p)\n", This
, index
, listItem
);
218 curr
= This
->parent
->children
;
221 if(nodeIndex
++ == index
) break;
224 if(!curr
) return S_FALSE
;
226 *listItem
= create_node( curr
);
231 static HRESULT WINAPI
xmlnodelist_get_length(
232 IXMLDOMNodeList
* iface
,
239 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
241 TRACE("(%p)->(%p)\n", This
, listLength
);
246 curr
= This
->parent
->children
;
253 *listLength
= nodeCount
;
257 static HRESULT WINAPI
xmlnodelist_nextNode(
258 IXMLDOMNodeList
* iface
,
259 IXMLDOMNode
** nextItem
)
261 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
263 TRACE("(%p)->(%p)\n", This
, nextItem
);
273 *nextItem
= create_node( This
->current
);
274 This
->current
= This
->current
->next
;
278 static HRESULT WINAPI
xmlnodelist_reset(
279 IXMLDOMNodeList
* iface
)
281 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
284 This
->current
= This
->parent
->children
;
288 static HRESULT WINAPI
xmlnodelist__newEnum(
289 IXMLDOMNodeList
* iface
,
292 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
293 FIXME("(%p)->(%p)\n", This
, ppUnk
);
298 static const struct IXMLDOMNodeListVtbl xmlnodelist_vtbl
=
300 xmlnodelist_QueryInterface
,
303 xmlnodelist_GetTypeInfoCount
,
304 xmlnodelist_GetTypeInfo
,
305 xmlnodelist_GetIDsOfNames
,
307 xmlnodelist_get_item
,
308 xmlnodelist_get_length
,
309 xmlnodelist_nextNode
,
311 xmlnodelist__newEnum
,
314 IXMLDOMNodeList
* create_children_nodelist( xmlNodePtr node
)
316 xmlnodelist
*nodelist
;
318 nodelist
= heap_alloc( sizeof *nodelist
);
322 nodelist
->lpVtbl
= &xmlnodelist_vtbl
;
324 nodelist
->parent
= node
;
325 nodelist
->current
= node
->children
;
327 xmldoc_add_ref( node
->doc
);
329 return (IXMLDOMNodeList
*) &nodelist
->lpVtbl
;