pdh: Implement and test PdhLookupPerfIndexByName{A, W} and PdhLookupPerfNameByIndex...
[wine] / dlls / msxml3 / nodelist.c
1 /*
2  *    Node list implementation
3  *
4  * Copyright 2005 Mike McCormack
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #define COBJMACROS
22
23 #include "config.h"
24
25 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "ole2.h"
30 #include "msxml2.h"
31
32 #include "msxml_private.h"
33
34 #include "wine/debug.h"
35
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
43  */
44
45 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
46
47 #ifdef HAVE_LIBXML2
48
49 typedef struct _xmlnodelist
50 {
51     const struct IXMLDOMNodeListVtbl *lpVtbl;
52     LONG ref;
53     xmlNodePtr parent;
54     xmlNodePtr current;
55 } xmlnodelist;
56
57 static inline xmlnodelist *impl_from_IXMLDOMNodeList( IXMLDOMNodeList *iface )
58 {
59     return (xmlnodelist *)((char*)iface - FIELD_OFFSET(xmlnodelist, lpVtbl));
60 }
61
62 static HRESULT WINAPI xmlnodelist_QueryInterface(
63     IXMLDOMNodeList *iface,
64     REFIID riid,
65     void** ppvObject )
66 {
67     TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject);
68
69     if ( IsEqualGUID( riid, &IID_IUnknown ) ||
70          IsEqualGUID( riid, &IID_IDispatch ) ||
71          IsEqualGUID( riid, &IID_IXMLDOMNodeList ) )
72     {
73         *ppvObject = iface;
74     }
75     else
76     {
77         FIXME("interface %s not implemented\n", debugstr_guid(riid));
78         *ppvObject = NULL;
79         return E_NOINTERFACE;
80     }
81
82     IXMLDOMNodeList_AddRef( iface );
83
84     return S_OK;
85 }
86
87 static ULONG WINAPI xmlnodelist_AddRef(
88     IXMLDOMNodeList *iface )
89 {
90     xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
91     return InterlockedIncrement( &This->ref );
92 }
93
94 static ULONG WINAPI xmlnodelist_Release(
95     IXMLDOMNodeList *iface )
96 {
97     xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
98     ULONG ref;
99
100     ref = InterlockedDecrement( &This->ref );
101     if ( ref == 0 )
102     {
103         xmldoc_release( This->parent->doc );
104         HeapFree( GetProcessHeap(), 0, This );
105     }
106
107     return ref;
108 }
109
110 static HRESULT WINAPI xmlnodelist_GetTypeInfoCount(
111     IXMLDOMNodeList *iface,
112     UINT* pctinfo )
113 {
114     FIXME("\n");
115     return E_NOTIMPL;
116 }
117
118 static HRESULT WINAPI xmlnodelist_GetTypeInfo(
119     IXMLDOMNodeList *iface,
120     UINT iTInfo,
121     LCID lcid,
122     ITypeInfo** ppTInfo )
123 {
124     FIXME("\n");
125     return E_NOTIMPL;
126 }
127
128 static HRESULT WINAPI xmlnodelist_GetIDsOfNames(
129     IXMLDOMNodeList *iface,
130     REFIID riid,
131     LPOLESTR* rgszNames,
132     UINT cNames,
133     LCID lcid,
134     DISPID* rgDispId )
135 {
136     FIXME("\n");
137     return E_NOTIMPL;
138 }
139
140 static HRESULT WINAPI xmlnodelist_Invoke(
141     IXMLDOMNodeList *iface,
142     DISPID dispIdMember,
143     REFIID riid,
144     LCID lcid,
145     WORD wFlags,
146     DISPPARAMS* pDispParams,
147     VARIANT* pVarResult,
148     EXCEPINFO* pExcepInfo,
149     UINT* puArgErr )
150 {
151     FIXME("\n");
152     return E_NOTIMPL;
153 }
154
155 static HRESULT WINAPI xmlnodelist_get_item(
156         IXMLDOMNodeList* iface,
157         long index,
158         IXMLDOMNode** listItem)
159 {
160     xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
161     xmlNodePtr curr;
162     long nodeIndex = 0;
163
164     TRACE("%p %ld\n", This, index);
165  
166     *listItem = NULL;
167
168     if (index < 0)
169         return S_FALSE;
170
171     curr = This->parent->children;
172     while(curr)
173     {
174         if(nodeIndex++ == index) break;
175         curr = curr->next;
176     }
177     if(!curr) return S_FALSE;
178
179     *listItem = create_node( curr );
180
181     return S_OK;
182 }
183
184 static HRESULT WINAPI xmlnodelist_get_length(
185         IXMLDOMNodeList* iface,
186         long* listLength)
187 {
188
189     xmlNodePtr curr;
190     long nodeCount = 0;
191
192     xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
193
194     TRACE("%p\n", This);
195
196     curr = This->parent->children;
197     while (curr)
198     {
199         nodeCount++;
200         curr = curr->next;
201     }
202
203     *listLength = nodeCount;
204     return S_OK;
205 }
206
207 static HRESULT WINAPI xmlnodelist_nextNode(
208         IXMLDOMNodeList* iface,
209         IXMLDOMNode** nextItem)
210 {
211     xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
212
213     TRACE("%p %p\n", This, nextItem );
214
215     *nextItem = NULL;
216
217     if (!This->current)
218         return S_FALSE;
219
220     *nextItem = create_node( This->current );
221     This->current = This->current->next;
222     return S_OK;
223 }
224
225 static HRESULT WINAPI xmlnodelist_reset(
226         IXMLDOMNodeList* iface)
227 {
228     xmlnodelist *This = impl_from_IXMLDOMNodeList( iface );
229
230     TRACE("%p\n", This);
231     This->current = This->parent->children;
232     return S_OK;
233 }
234
235 static HRESULT WINAPI xmlnodelist__newEnum(
236         IXMLDOMNodeList* iface,
237         IUnknown** ppUnk)
238 {
239     FIXME("\n");
240     return E_NOTIMPL;
241 }
242
243
244 static const struct IXMLDOMNodeListVtbl xmlnodelist_vtbl =
245 {
246     xmlnodelist_QueryInterface,
247     xmlnodelist_AddRef,
248     xmlnodelist_Release,
249     xmlnodelist_GetTypeInfoCount,
250     xmlnodelist_GetTypeInfo,
251     xmlnodelist_GetIDsOfNames,
252     xmlnodelist_Invoke,
253     xmlnodelist_get_item,
254     xmlnodelist_get_length,
255     xmlnodelist_nextNode,
256     xmlnodelist_reset,
257     xmlnodelist__newEnum,
258 };
259
260 IXMLDOMNodeList* create_children_nodelist( xmlNodePtr node )
261 {
262     xmlnodelist *nodelist;
263
264     nodelist = HeapAlloc( GetProcessHeap(), 0, sizeof *nodelist );
265     if ( !nodelist )
266         return NULL;
267
268     nodelist->lpVtbl = &xmlnodelist_vtbl;
269     nodelist->ref = 1;
270     nodelist->parent = node;
271     nodelist->current = node->children;
272
273     xmldoc_add_ref( node->doc );
274
275     return (IXMLDOMNodeList*) &nodelist->lpVtbl;
276 }
277
278 #endif