dsound: Don't specify period size for the IAudioClient.
[wine] / dlls / msxml3 / nodemap.c
1 /*
2  *    Node map 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 #include "config.h"
22
23 #define COBJMACROS
24
25 #include <stdarg.h>
26 #ifdef HAVE_LIBXML2
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 #endif
30
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winuser.h"
34 #include "winnls.h"
35 #include "ole2.h"
36 #include "msxml6.h"
37 #include "msxml2did.h"
38
39 #include "msxml_private.h"
40
41 #include "wine/debug.h"
42
43 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
44
45 #ifdef HAVE_LIBXML2
46
47 typedef struct _xmlnodemap
48 {
49     DispatchEx dispex;
50     IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface;
51     ISupportErrorInfo ISupportErrorInfo_iface;
52     LONG ref;
53
54     xmlNodePtr node;
55     LONG iterator;
56
57     const struct nodemap_funcs *funcs;
58 } xmlnodemap;
59
60 static inline xmlnodemap *impl_from_IXMLDOMNamedNodeMap( IXMLDOMNamedNodeMap *iface )
61 {
62     return CONTAINING_RECORD(iface, xmlnodemap, IXMLDOMNamedNodeMap_iface);
63 }
64
65 static inline xmlnodemap *impl_from_ISupportErrorInfo( ISupportErrorInfo *iface )
66 {
67     return CONTAINING_RECORD(iface, xmlnodemap, ISupportErrorInfo_iface);
68 }
69
70 static HRESULT WINAPI xmlnodemap_QueryInterface(
71     IXMLDOMNamedNodeMap *iface,
72     REFIID riid, void** ppvObject )
73 {
74     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
75     TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);
76
77     if( IsEqualGUID( riid, &IID_IUnknown ) ||
78         IsEqualGUID( riid, &IID_IDispatch ) ||
79         IsEqualGUID( riid, &IID_IXMLDOMNamedNodeMap ) )
80     {
81         *ppvObject = iface;
82     }
83     else if (dispex_query_interface(&This->dispex, riid, ppvObject))
84     {
85         return *ppvObject ? S_OK : E_NOINTERFACE;
86     }
87     else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
88     {
89         *ppvObject = &This->ISupportErrorInfo_iface;
90     }
91     else
92     {
93         TRACE("interface %s not implemented\n", debugstr_guid(riid));
94         *ppvObject = NULL;
95         return E_NOINTERFACE;
96     }
97
98     IXMLDOMElement_AddRef( iface );
99
100     return S_OK;
101 }
102
103 static ULONG WINAPI xmlnodemap_AddRef(
104     IXMLDOMNamedNodeMap *iface )
105 {
106     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
107     ULONG ref = InterlockedIncrement( &This->ref );
108     TRACE("(%p)->(%d)\n", This, ref);
109     return ref;
110 }
111
112 static ULONG WINAPI xmlnodemap_Release(
113     IXMLDOMNamedNodeMap *iface )
114 {
115     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
116     ULONG ref = InterlockedDecrement( &This->ref );
117
118     TRACE("(%p)->(%d)\n", This, ref);
119     if ( ref == 0 )
120     {
121         xmldoc_release( This->node->doc );
122         release_dispex(&This->dispex);
123         heap_free( This );
124     }
125
126     return ref;
127 }
128
129 static HRESULT WINAPI xmlnodemap_GetTypeInfoCount(
130     IXMLDOMNamedNodeMap *iface,
131     UINT* pctinfo )
132 {
133     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
134
135     TRACE("(%p)->(%p)\n", This, pctinfo);
136
137     *pctinfo = 1;
138
139     return S_OK;
140 }
141
142 static HRESULT WINAPI xmlnodemap_GetTypeInfo(
143     IXMLDOMNamedNodeMap *iface,
144     UINT iTInfo, LCID lcid,
145     ITypeInfo** ppTInfo )
146 {
147     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
148     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
149     return get_typeinfo(IXMLDOMNamedNodeMap_tid, ppTInfo);
150 }
151
152 static HRESULT WINAPI xmlnodemap_GetIDsOfNames(
153     IXMLDOMNamedNodeMap *iface,
154     REFIID riid, LPOLESTR* rgszNames,
155     UINT cNames, LCID lcid, DISPID* rgDispId )
156 {
157     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
158     ITypeInfo *typeinfo;
159     HRESULT hr;
160
161     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
162           lcid, rgDispId);
163
164     if(!rgszNames || cNames == 0 || !rgDispId)
165         return E_INVALIDARG;
166
167     hr = get_typeinfo(IXMLDOMNamedNodeMap_tid, &typeinfo);
168     if(SUCCEEDED(hr))
169     {
170         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
171         ITypeInfo_Release(typeinfo);
172     }
173
174     return hr;
175 }
176
177 static HRESULT WINAPI xmlnodemap_Invoke(
178     IXMLDOMNamedNodeMap *iface,
179     DISPID dispIdMember, REFIID riid, LCID lcid,
180     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
181     EXCEPINFO* pExcepInfo, UINT* puArgErr )
182 {
183     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
184     ITypeInfo *typeinfo;
185     HRESULT hr;
186
187     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
188           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
189
190     hr = get_typeinfo(IXMLDOMNamedNodeMap_tid, &typeinfo);
191     if(SUCCEEDED(hr))
192     {
193         hr = ITypeInfo_Invoke(typeinfo, &This->IXMLDOMNamedNodeMap_iface, dispIdMember, wFlags,
194                 pDispParams, pVarResult, pExcepInfo, puArgErr);
195         ITypeInfo_Release(typeinfo);
196     }
197
198     return hr;
199 }
200
201 static HRESULT WINAPI xmlnodemap_getNamedItem(
202     IXMLDOMNamedNodeMap *iface,
203     BSTR name,
204     IXMLDOMNode** item)
205 {
206     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
207
208     TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), item );
209
210     return This->funcs->get_named_item(This->node, name, item);
211 }
212
213 static HRESULT WINAPI xmlnodemap_setNamedItem(
214     IXMLDOMNamedNodeMap *iface,
215     IXMLDOMNode* newItem,
216     IXMLDOMNode** namedItem)
217 {
218     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
219
220     TRACE("(%p)->(%p %p)\n", This, newItem, namedItem );
221
222     return This->funcs->set_named_item(This->node, newItem, namedItem);
223 }
224
225 static HRESULT WINAPI xmlnodemap_removeNamedItem(
226     IXMLDOMNamedNodeMap *iface,
227     BSTR name,
228     IXMLDOMNode** namedItem)
229 {
230     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
231
232     TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), namedItem );
233
234     return This->funcs->remove_named_item(This->node, name, namedItem);
235 }
236
237 static HRESULT WINAPI xmlnodemap_get_item(
238     IXMLDOMNamedNodeMap *iface,
239     LONG index,
240     IXMLDOMNode** item)
241 {
242     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
243
244     TRACE("(%p)->(%d %p)\n", This, index, item);
245
246     return This->funcs->get_item(This->node, index, item);
247 }
248
249 static HRESULT WINAPI xmlnodemap_get_length(
250     IXMLDOMNamedNodeMap *iface,
251     LONG *length)
252 {
253     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
254
255     TRACE("(%p)->(%p)\n", This, length);
256
257     return This->funcs->get_length(This->node, length);
258 }
259
260 static HRESULT WINAPI xmlnodemap_getQualifiedItem(
261     IXMLDOMNamedNodeMap *iface,
262     BSTR baseName,
263     BSTR namespaceURI,
264     IXMLDOMNode** item)
265 {
266     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
267
268     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), item);
269
270     return This->funcs->get_qualified_item(This->node, baseName, namespaceURI, item);
271 }
272
273 static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
274     IXMLDOMNamedNodeMap *iface,
275     BSTR baseName,
276     BSTR namespaceURI,
277     IXMLDOMNode** item)
278 {
279     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
280
281     ERR("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), item);
282
283     return This->funcs->remove_qualified_item(This->node, baseName, namespaceURI, item);
284 }
285
286 static HRESULT WINAPI xmlnodemap_nextNode(
287     IXMLDOMNamedNodeMap *iface,
288     IXMLDOMNode** nextItem)
289 {
290     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
291
292     TRACE("(%p)->(%p: %d)\n", This, nextItem, This->iterator);
293
294     return This->funcs->next_node(This->node, &This->iterator, nextItem);
295 }
296
297 static HRESULT WINAPI xmlnodemap_reset(
298     IXMLDOMNamedNodeMap *iface )
299 {
300     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
301
302     TRACE("(%p: %d)\n", This, This->iterator);
303
304     This->iterator = 0;
305
306     return S_OK;
307 }
308
309 static HRESULT WINAPI xmlnodemap__newEnum(
310     IXMLDOMNamedNodeMap *iface,
311     IUnknown** ppUnk)
312 {
313     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
314     FIXME("(%p)->(%p)\n", This, ppUnk);
315     return E_NOTIMPL;
316 }
317
318 static const struct IXMLDOMNamedNodeMapVtbl xmlnodemap_vtbl =
319 {
320     xmlnodemap_QueryInterface,
321     xmlnodemap_AddRef,
322     xmlnodemap_Release,
323     xmlnodemap_GetTypeInfoCount,
324     xmlnodemap_GetTypeInfo,
325     xmlnodemap_GetIDsOfNames,
326     xmlnodemap_Invoke,
327     xmlnodemap_getNamedItem,
328     xmlnodemap_setNamedItem,
329     xmlnodemap_removeNamedItem,
330     xmlnodemap_get_item,
331     xmlnodemap_get_length,
332     xmlnodemap_getQualifiedItem,
333     xmlnodemap_removeQualifiedItem,
334     xmlnodemap_nextNode,
335     xmlnodemap_reset,
336     xmlnodemap__newEnum,
337 };
338
339 static HRESULT WINAPI support_error_QueryInterface(
340     ISupportErrorInfo *iface,
341     REFIID riid, void** ppvObject )
342 {
343     xmlnodemap *This = impl_from_ISupportErrorInfo( iface );
344     TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject);
345     return IXMLDOMNamedNodeMap_QueryInterface(&This->IXMLDOMNamedNodeMap_iface, riid, ppvObject);
346 }
347
348 static ULONG WINAPI support_error_AddRef(
349     ISupportErrorInfo *iface )
350 {
351     xmlnodemap *This = impl_from_ISupportErrorInfo( iface );
352     return IXMLDOMNamedNodeMap_AddRef(&This->IXMLDOMNamedNodeMap_iface);
353 }
354
355 static ULONG WINAPI support_error_Release(
356     ISupportErrorInfo *iface )
357 {
358     xmlnodemap *This = impl_from_ISupportErrorInfo( iface );
359     return IXMLDOMNamedNodeMap_Release(&This->IXMLDOMNamedNodeMap_iface);
360 }
361
362 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
363     ISupportErrorInfo *iface,
364     REFIID riid )
365 {
366     FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
367     return S_FALSE;
368 }
369
370 static const struct ISupportErrorInfoVtbl support_error_vtbl =
371 {
372     support_error_QueryInterface,
373     support_error_AddRef,
374     support_error_Release,
375     support_error_InterfaceSupportsErrorInfo
376 };
377
378 static HRESULT xmlnodemap_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid)
379 {
380     WCHAR *ptr;
381     int idx = 0;
382
383     for(ptr = name; *ptr && isdigitW(*ptr); ptr++)
384         idx = idx*10 + (*ptr-'0');
385     if(*ptr)
386         return DISP_E_UNKNOWNNAME;
387
388     *dispid = DISPID_DOM_COLLECTION_BASE + idx;
389     TRACE("ret %x\n", *dispid);
390     return S_OK;
391 }
392
393 static HRESULT xmlnodemap_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
394         VARIANT *res, EXCEPINFO *ei)
395 {
396     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( (IXMLDOMNamedNodeMap*)iface );
397
398     TRACE("(%p)->(%x %x %x %p %p %p)\n", This, id, lcid, flags, params, res, ei);
399
400     V_VT(res) = VT_DISPATCH;
401     V_DISPATCH(res) = NULL;
402
403     if (id < DISPID_DOM_COLLECTION_BASE || id > DISPID_DOM_COLLECTION_MAX)
404         return DISP_E_UNKNOWNNAME;
405
406     switch(flags)
407     {
408         case INVOKE_PROPERTYGET:
409         {
410             IXMLDOMNode *disp = NULL;
411
412             IXMLDOMNamedNodeMap_get_item(&This->IXMLDOMNamedNodeMap_iface, id - DISPID_DOM_COLLECTION_BASE, &disp);
413             V_DISPATCH(res) = (IDispatch*)disp;
414             break;
415         }
416         default:
417         {
418             FIXME("unimplemented flags %x\n", flags);
419             break;
420         }
421     }
422
423     TRACE("ret %p\n", V_DISPATCH(res));
424
425     return S_OK;
426 }
427
428 static const dispex_static_data_vtbl_t xmlnodemap_dispex_vtbl = {
429     xmlnodemap_get_dispid,
430     xmlnodemap_invoke
431 };
432
433 static const tid_t xmlnodemap_iface_tids[] = {
434     IXMLDOMNamedNodeMap_tid,
435     0
436 };
437
438 static dispex_static_data_t xmlnodemap_dispex = {
439     &xmlnodemap_dispex_vtbl,
440     IXMLDOMNamedNodeMap_tid,
441     NULL,
442     xmlnodemap_iface_tids
443 };
444
445 IXMLDOMNamedNodeMap *create_nodemap(xmlNodePtr node, const struct nodemap_funcs *funcs)
446 {
447     xmlnodemap *This;
448
449     This = heap_alloc( sizeof *This );
450     if ( !This )
451         return NULL;
452
453     This->IXMLDOMNamedNodeMap_iface.lpVtbl = &xmlnodemap_vtbl;
454     This->ISupportErrorInfo_iface.lpVtbl = &support_error_vtbl;
455     This->node = node;
456     This->ref = 1;
457     This->iterator = 0;
458     This->funcs = funcs;
459
460     init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex);
461
462     xmldoc_add_ref(node->doc);
463
464     return &This->IXMLDOMNamedNodeMap_iface;
465 }
466
467 #endif