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
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
37 #include "msxml_private.h"
39 #include "wine/debug.h"
41 /* This file implements the object returned by childNodes property. Note that this is
42 * not the IXMLDOMNodeList returned by XPath querites - it's implemented in queryresult.c.
43 * They are different because the list returned by childNodes:
44 * - is "live" - changes to the XML tree are automatically reflected in the list
45 * - doesn't supports IXMLDOMSelection
46 * - note that an attribute node have a text child in DOM but not in the XPath data model
47 * thus the child is inaccessible by an XPath query
50 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
54 typedef struct _xmlnodelist
56 IXMLDOMNodeList IXMLDOMNodeList_iface
;
62 static inline xmlnodelist
*impl_from_IXMLDOMNodeList( IXMLDOMNodeList
*iface
)
64 return CONTAINING_RECORD(iface
, xmlnodelist
, IXMLDOMNodeList_iface
);
67 static HRESULT WINAPI
xmlnodelist_QueryInterface(
68 IXMLDOMNodeList
*iface
,
72 TRACE("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppvObject
);
74 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
75 IsEqualGUID( riid
, &IID_IDispatch
) ||
76 IsEqualGUID( riid
, &IID_IXMLDOMNodeList
) )
82 TRACE("interface %s not implemented\n", debugstr_guid(riid
));
87 IXMLDOMNodeList_AddRef( iface
);
92 static ULONG WINAPI
xmlnodelist_AddRef(
93 IXMLDOMNodeList
*iface
)
95 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
96 ULONG ref
= InterlockedIncrement( &This
->ref
);
97 TRACE("(%p)->(%d)\n", This
, ref
);
101 static ULONG WINAPI
xmlnodelist_Release(
102 IXMLDOMNodeList
*iface
)
104 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
105 ULONG ref
= InterlockedDecrement( &This
->ref
);
107 TRACE("(%p)->(%d)\n", This
, ref
);
110 xmldoc_release( This
->parent
->doc
);
117 static HRESULT WINAPI
xmlnodelist_GetTypeInfoCount(
118 IXMLDOMNodeList
*iface
,
121 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
123 TRACE("(%p)->(%p)\n", This
, pctinfo
);
130 static HRESULT WINAPI
xmlnodelist_GetTypeInfo(
131 IXMLDOMNodeList
*iface
,
134 ITypeInfo
** ppTInfo
)
136 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
139 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
141 hr
= get_typeinfo(IXMLDOMNodeList_tid
, ppTInfo
);
146 static HRESULT WINAPI
xmlnodelist_GetIDsOfNames(
147 IXMLDOMNodeList
*iface
,
154 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
158 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
161 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
164 hr
= get_typeinfo(IXMLDOMNodeList_tid
, &typeinfo
);
167 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
168 ITypeInfo_Release(typeinfo
);
174 static HRESULT WINAPI
xmlnodelist_Invoke(
175 IXMLDOMNodeList
*iface
,
180 DISPPARAMS
* pDispParams
,
182 EXCEPINFO
* pExcepInfo
,
185 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
189 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
190 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
192 hr
= get_typeinfo(IXMLDOMNodeList_tid
, &typeinfo
);
195 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IXMLDOMNodeList_iface
, dispIdMember
, wFlags
,
196 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
197 ITypeInfo_Release(typeinfo
);
203 static HRESULT WINAPI
xmlnodelist_get_item(
204 IXMLDOMNodeList
* iface
,
206 IXMLDOMNode
** listItem
)
208 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
212 TRACE("(%p)->(%d %p)\n", This
, index
, listItem
);
222 curr
= This
->parent
->children
;
225 if(nodeIndex
++ == index
) break;
228 if(!curr
) return S_FALSE
;
230 *listItem
= create_node( curr
);
235 static HRESULT WINAPI
xmlnodelist_get_length(
236 IXMLDOMNodeList
* iface
,
243 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
245 TRACE("(%p)->(%p)\n", This
, listLength
);
250 curr
= This
->parent
->children
;
257 *listLength
= nodeCount
;
261 static HRESULT WINAPI
xmlnodelist_nextNode(
262 IXMLDOMNodeList
* iface
,
263 IXMLDOMNode
** nextItem
)
265 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
267 TRACE("(%p)->(%p)\n", This
, nextItem
);
277 *nextItem
= create_node( This
->current
);
278 This
->current
= This
->current
->next
;
282 static HRESULT WINAPI
xmlnodelist_reset(
283 IXMLDOMNodeList
* iface
)
285 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
288 This
->current
= This
->parent
->children
;
292 static HRESULT WINAPI
xmlnodelist__newEnum(
293 IXMLDOMNodeList
* iface
,
296 xmlnodelist
*This
= impl_from_IXMLDOMNodeList( iface
);
297 FIXME("(%p)->(%p)\n", This
, ppUnk
);
302 static const struct IXMLDOMNodeListVtbl xmlnodelist_vtbl
=
304 xmlnodelist_QueryInterface
,
307 xmlnodelist_GetTypeInfoCount
,
308 xmlnodelist_GetTypeInfo
,
309 xmlnodelist_GetIDsOfNames
,
311 xmlnodelist_get_item
,
312 xmlnodelist_get_length
,
313 xmlnodelist_nextNode
,
315 xmlnodelist__newEnum
,
318 IXMLDOMNodeList
* create_children_nodelist( xmlNodePtr node
)
320 xmlnodelist
*nodelist
;
322 nodelist
= heap_alloc( sizeof *nodelist
);
326 nodelist
->IXMLDOMNodeList_iface
.lpVtbl
= &xmlnodelist_vtbl
;
328 nodelist
->parent
= node
;
329 nodelist
->current
= node
->children
;
331 xmldoc_add_ref( node
->doc
);
333 return &nodelist
->IXMLDOMNodeList_iface
;