ReactOS  0.4.15-dev-4872-g8a3db97
nodemap.c
Go to the documentation of this file.
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 #ifdef HAVE_LIBXML2
44 
46 
47 typedef struct
48 {
49  DispatchEx dispex;
50  IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface;
51  ISupportErrorInfo ISupportErrorInfo_iface;
52  LONG ref;
53 
55  LONG iterator;
57 
58  const struct nodemap_funcs *funcs;
59 } xmlnodemap;
60 
61 static HRESULT nodemap_get_item(IUnknown *iface, LONG index, VARIANT *item)
62 {
64  return IXMLDOMNamedNodeMap_get_item((IXMLDOMNamedNodeMap*)iface, index, (IXMLDOMNode**)&V_DISPATCH(item));
65 }
66 
67 static const struct enumvariant_funcs nodemap_enumvariant = {
68  nodemap_get_item,
69  NULL
70 };
71 
72 static inline xmlnodemap *impl_from_IXMLDOMNamedNodeMap( IXMLDOMNamedNodeMap *iface )
73 {
74  return CONTAINING_RECORD(iface, xmlnodemap, IXMLDOMNamedNodeMap_iface);
75 }
76 
77 static inline xmlnodemap *impl_from_ISupportErrorInfo( ISupportErrorInfo *iface )
78 {
79  return CONTAINING_RECORD(iface, xmlnodemap, ISupportErrorInfo_iface);
80 }
81 
82 static HRESULT WINAPI xmlnodemap_QueryInterface(
83  IXMLDOMNamedNodeMap *iface,
84  REFIID riid, void** ppvObject )
85 {
86  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
87  TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);
88 
89  if( IsEqualGUID( riid, &IID_IUnknown ) ||
91  IsEqualGUID( riid, &IID_IXMLDOMNamedNodeMap ) )
92  {
93  *ppvObject = iface;
94  }
95  else if (IsEqualGUID( riid, &IID_IEnumVARIANT ))
96  {
97  if (!This->enumvariant)
98  {
99  HRESULT hr = create_enumvariant((IUnknown*)iface, FALSE, &nodemap_enumvariant, &This->enumvariant);
100  if (FAILED(hr)) return hr;
101  }
102 
103  return IEnumVARIANT_QueryInterface(This->enumvariant, &IID_IEnumVARIANT, ppvObject);
104  }
105  else if (dispex_query_interface(&This->dispex, riid, ppvObject))
106  {
107  return *ppvObject ? S_OK : E_NOINTERFACE;
108  }
109  else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
110  {
111  *ppvObject = &This->ISupportErrorInfo_iface;
112  }
113  else
114  {
115  TRACE("interface %s not implemented\n", debugstr_guid(riid));
116  *ppvObject = NULL;
117  return E_NOINTERFACE;
118  }
119 
120  IXMLDOMNamedNodeMap_AddRef( iface );
121 
122  return S_OK;
123 }
124 
125 static ULONG WINAPI xmlnodemap_AddRef(
126  IXMLDOMNamedNodeMap *iface )
127 {
128  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
129  ULONG ref = InterlockedIncrement( &This->ref );
130  TRACE("(%p)->(%d)\n", This, ref);
131  return ref;
132 }
133 
134 static ULONG WINAPI xmlnodemap_Release(
135  IXMLDOMNamedNodeMap *iface )
136 {
137  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
138  ULONG ref = InterlockedDecrement( &This->ref );
139 
140  TRACE("(%p)->(%d)\n", This, ref);
141  if ( ref == 0 )
142  {
143  xmlnode_release( This->node );
144  xmldoc_release( This->node->doc );
145  if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant);
146  heap_free( This );
147  }
148 
149  return ref;
150 }
151 
152 static HRESULT WINAPI xmlnodemap_GetTypeInfoCount(
153  IXMLDOMNamedNodeMap *iface,
154  UINT* pctinfo )
155 {
156  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
157  return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
158 }
159 
160 static HRESULT WINAPI xmlnodemap_GetTypeInfo(
161  IXMLDOMNamedNodeMap *iface,
162  UINT iTInfo, LCID lcid,
163  ITypeInfo** ppTInfo )
164 {
165  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
166  return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
167  iTInfo, lcid, ppTInfo);
168 }
169 
170 static HRESULT WINAPI xmlnodemap_GetIDsOfNames(
171  IXMLDOMNamedNodeMap *iface,
172  REFIID riid, LPOLESTR* rgszNames,
173  UINT cNames, LCID lcid, DISPID* rgDispId )
174 {
175  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
176  return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
177  riid, rgszNames, cNames, lcid, rgDispId);
178 }
179 
180 static HRESULT WINAPI xmlnodemap_Invoke(
181  IXMLDOMNamedNodeMap *iface,
182  DISPID dispIdMember, REFIID riid, LCID lcid,
183  WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
184  EXCEPINFO* pExcepInfo, UINT* puArgErr )
185 {
186  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
187  return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
188  dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
189 }
190 
191 static HRESULT WINAPI xmlnodemap_getNamedItem(
192  IXMLDOMNamedNodeMap *iface,
193  BSTR name,
194  IXMLDOMNode** item)
195 {
196  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
197 
198  TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), item );
199 
200  return This->funcs->get_named_item(This->node, name, item);
201 }
202 
203 static HRESULT WINAPI xmlnodemap_setNamedItem(
204  IXMLDOMNamedNodeMap *iface,
205  IXMLDOMNode* newItem,
206  IXMLDOMNode** namedItem)
207 {
208  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
209 
210  TRACE("(%p)->(%p %p)\n", This, newItem, namedItem );
211 
212  return This->funcs->set_named_item(This->node, newItem, namedItem);
213 }
214 
215 static HRESULT WINAPI xmlnodemap_removeNamedItem(
216  IXMLDOMNamedNodeMap *iface,
217  BSTR name,
218  IXMLDOMNode** namedItem)
219 {
220  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
221 
222  TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), namedItem );
223 
224  return This->funcs->remove_named_item(This->node, name, namedItem);
225 }
226 
227 static HRESULT WINAPI xmlnodemap_get_item(
228  IXMLDOMNamedNodeMap *iface,
229  LONG index,
230  IXMLDOMNode** item)
231 {
232  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
233 
234  TRACE("(%p)->(%d %p)\n", This, index, item);
235 
236  return This->funcs->get_item(This->node, index, item);
237 }
238 
239 static HRESULT WINAPI xmlnodemap_get_length(
240  IXMLDOMNamedNodeMap *iface,
241  LONG *length)
242 {
243  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
244 
245  TRACE("(%p)->(%p)\n", This, length);
246 
247  return This->funcs->get_length(This->node, length);
248 }
249 
250 static HRESULT WINAPI xmlnodemap_getQualifiedItem(
251  IXMLDOMNamedNodeMap *iface,
252  BSTR baseName,
253  BSTR namespaceURI,
254  IXMLDOMNode** item)
255 {
256  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
257 
258  TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), item);
259 
260  return This->funcs->get_qualified_item(This->node, baseName, namespaceURI, item);
261 }
262 
263 static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
264  IXMLDOMNamedNodeMap *iface,
265  BSTR baseName,
266  BSTR namespaceURI,
267  IXMLDOMNode** item)
268 {
269  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
270 
271  TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), item);
272 
273  return This->funcs->remove_qualified_item(This->node, baseName, namespaceURI, item);
274 }
275 
276 static HRESULT WINAPI xmlnodemap_nextNode(
277  IXMLDOMNamedNodeMap *iface,
278  IXMLDOMNode** nextItem)
279 {
280  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
281 
282  TRACE("(%p)->(%p: %d)\n", This, nextItem, This->iterator);
283 
284  return This->funcs->next_node(This->node, &This->iterator, nextItem);
285 }
286 
287 static HRESULT WINAPI xmlnodemap_reset(
288  IXMLDOMNamedNodeMap *iface )
289 {
290  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
291 
292  TRACE("(%p)->(%d)\n", This, This->iterator);
293 
294  This->iterator = 0;
295 
296  return S_OK;
297 }
298 
299 static HRESULT WINAPI xmlnodemap__newEnum(
300  IXMLDOMNamedNodeMap *iface,
301  IUnknown** enumv)
302 {
303  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
304  TRACE("(%p)->(%p)\n", This, enumv);
305  return create_enumvariant((IUnknown*)iface, TRUE, &nodemap_enumvariant, (IEnumVARIANT**)enumv);
306 }
307 
308 static const struct IXMLDOMNamedNodeMapVtbl XMLDOMNamedNodeMapVtbl =
309 {
310  xmlnodemap_QueryInterface,
311  xmlnodemap_AddRef,
312  xmlnodemap_Release,
313  xmlnodemap_GetTypeInfoCount,
314  xmlnodemap_GetTypeInfo,
315  xmlnodemap_GetIDsOfNames,
316  xmlnodemap_Invoke,
317  xmlnodemap_getNamedItem,
318  xmlnodemap_setNamedItem,
319  xmlnodemap_removeNamedItem,
320  xmlnodemap_get_item,
321  xmlnodemap_get_length,
322  xmlnodemap_getQualifiedItem,
323  xmlnodemap_removeQualifiedItem,
324  xmlnodemap_nextNode,
325  xmlnodemap_reset,
326  xmlnodemap__newEnum,
327 };
328 
329 static HRESULT WINAPI support_error_QueryInterface(
330  ISupportErrorInfo *iface,
331  REFIID riid, void** ppvObject )
332 {
333  xmlnodemap *This = impl_from_ISupportErrorInfo( iface );
334  TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
335  return IXMLDOMNamedNodeMap_QueryInterface(&This->IXMLDOMNamedNodeMap_iface, riid, ppvObject);
336 }
337 
338 static ULONG WINAPI support_error_AddRef(
339  ISupportErrorInfo *iface )
340 {
341  xmlnodemap *This = impl_from_ISupportErrorInfo( iface );
342  return IXMLDOMNamedNodeMap_AddRef(&This->IXMLDOMNamedNodeMap_iface);
343 }
344 
345 static ULONG WINAPI support_error_Release(
346  ISupportErrorInfo *iface )
347 {
348  xmlnodemap *This = impl_from_ISupportErrorInfo( iface );
349  return IXMLDOMNamedNodeMap_Release(&This->IXMLDOMNamedNodeMap_iface);
350 }
351 
352 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
353  ISupportErrorInfo *iface,
354  REFIID riid )
355 {
356  xmlnodemap *This = impl_from_ISupportErrorInfo( iface );
357  TRACE("(%p)->(%s)\n", This, debugstr_guid(riid));
358  return IsEqualGUID(riid, &IID_IXMLDOMNamedNodeMap) ? S_OK : S_FALSE;
359 }
360 
361 static const struct ISupportErrorInfoVtbl SupportErrorInfoVtbl =
362 {
363  support_error_QueryInterface,
364  support_error_AddRef,
365  support_error_Release,
366  support_error_InterfaceSupportsErrorInfo
367 };
368 
369 static HRESULT xmlnodemap_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid)
370 {
371  WCHAR *ptr;
372  int idx = 0;
373 
374  for(ptr = name; *ptr && isdigitW(*ptr); ptr++)
375  idx = idx*10 + (*ptr-'0');
376  if(*ptr)
377  return DISP_E_UNKNOWNNAME;
378 
379  *dispid = DISPID_DOM_COLLECTION_BASE + idx;
380  TRACE("ret %x\n", *dispid);
381  return S_OK;
382 }
383 
384 static HRESULT xmlnodemap_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
385  VARIANT *res, EXCEPINFO *ei)
386 {
387  xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( (IXMLDOMNamedNodeMap*)iface );
388 
389  TRACE("(%p)->(%x %x %x %p %p %p)\n", This, id, lcid, flags, params, res, ei);
390 
391  V_VT(res) = VT_DISPATCH;
392  V_DISPATCH(res) = NULL;
393 
395  return DISP_E_UNKNOWNNAME;
396 
397  switch(flags)
398  {
399  case INVOKE_PROPERTYGET:
400  {
401  IXMLDOMNode *disp = NULL;
402 
403  IXMLDOMNamedNodeMap_get_item(&This->IXMLDOMNamedNodeMap_iface, id - DISPID_DOM_COLLECTION_BASE, &disp);
404  V_DISPATCH(res) = (IDispatch*)disp;
405  break;
406  }
407  default:
408  {
409  FIXME("unimplemented flags %x\n", flags);
410  break;
411  }
412  }
413 
414  TRACE("ret %p\n", V_DISPATCH(res));
415 
416  return S_OK;
417 }
418 
419 static const dispex_static_data_vtbl_t xmlnodemap_dispex_vtbl = {
420  xmlnodemap_get_dispid,
421  xmlnodemap_invoke
422 };
423 
424 static const tid_t xmlnodemap_iface_tids[] = {
426  0
427 };
428 
429 static dispex_static_data_t xmlnodemap_dispex = {
430  &xmlnodemap_dispex_vtbl,
432  NULL,
433  xmlnodemap_iface_tids
434 };
435 
436 IXMLDOMNamedNodeMap *create_nodemap(xmlNodePtr node, const struct nodemap_funcs *funcs)
437 {
438  xmlnodemap *This;
439 
440  This = heap_alloc( sizeof *This );
441  if ( !This )
442  return NULL;
443 
444  This->IXMLDOMNamedNodeMap_iface.lpVtbl = &XMLDOMNamedNodeMapVtbl;
445  This->ISupportErrorInfo_iface.lpVtbl = &SupportErrorInfoVtbl;
446  This->node = node;
447  This->ref = 1;
448  This->iterator = 0;
449  This->enumvariant = NULL;
450  This->funcs = funcs;
451 
452  init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex);
453 
454  xmlnode_add_ref(node);
455  xmldoc_add_ref(node->doc);
456 
457  return &This->IXMLDOMNamedNodeMap_iface;
458 }
459 
460 #endif
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
#define REFIID
Definition: guiddef.h:118
#define E_NOINTERFACE
Definition: winerror.h:2364
HRESULT hr
Definition: shlfolder.c:183
#define TRUE
Definition: types.h:120
REFIID riid
Definition: precomp.h:44
tid_t
Definition: ieframe.h:311
#define DISPID_DOM_COLLECTION_BASE
Definition: msxml2did.h:70
DWORD LCID
Definition: nls.h:13
OLECHAR * BSTR
Definition: compat.h:2152
#define DISPID_DOM_COLLECTION_MAX
Definition: msxml2did.h:71
static LPOLESTR
Definition: stg_prop.c:27
Definition: send.c:48
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define V_DISPATCH(A)
Definition: oleauto.h:239
struct node node
#define FALSE
Definition: types.h:117
GLenum const GLfloat * params
Definition: glext.h:5645
long LONG
Definition: pedump.c:60
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:111
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static PVOID ptr
Definition: dispmode.c:27
unsigned int idx
Definition: utils.c:41
#define S_FALSE
Definition: winerror.h:2357
GLuint index
Definition: glext.h:6031
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:6
static struct __wine_debug_functions funcs
Definition: debug.c:59
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
GLbitfield flags
Definition: glext.h:7161
Definition: tree.h:489
const GUID IID_IDispatch
#define InterlockedDecrement
Definition: armddk.h:52
#define V_VT(A)
Definition: oleauto.h:211
REFIID LPVOID * ppvObject
Definition: precomp.h:44
WDF_CHILD_LIST_ITERATOR iterator
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
struct stdole::EXCEPINFO EXCEPINFO
static VARIANTARG static DISPID
Definition: ordinal.c:49
#define S_OK
Definition: intsafe.h:52
#define InterlockedIncrement
Definition: armddk.h:53
static ATOM item
Definition: dde.c:856
BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
Definition: dispex.c:1656
WINE_UNICODE_INLINE int isdigitW(WCHAR wc)
Definition: unicode.h:170
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:919
Definition: name.c:38
GLuint res
Definition: glext.h:9613
struct stdole::DISPPARAMS DISPPARAMS
static HTMLDocument * impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
Definition: htmldoc.c:3948
unsigned int ULONG
Definition: retypes.h:1
GLenum GLuint id
Definition: glext.h:5579
static const ISupportErrorInfoVtbl SupportErrorInfoVtbl
Definition: htmldoc.c:3977
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
Definition: dlist.c:348