ReactOS 0.4.15-dev-7907-g95bf896
selection.c
Go to the documentation of this file.
1/*
2 * XPath/XSLPattern query result node list implementation
3 *
4 * Copyright 2005 Mike McCormack
5 * Copyright 2007 Mikolaj Zalewski
6 * Copyright 2010 Adam Martinson for CodeWeavers
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23#define COBJMACROS
24
25#include "config.h"
26
27#include <stdarg.h>
28#ifdef HAVE_LIBXML2
29# include <libxml/parser.h>
30# include <libxml/xmlerror.h>
31# include <libxml/xpath.h>
33#endif
34
35#include "windef.h"
36#include "winbase.h"
37#include "winuser.h"
38#include "ole2.h"
39#include "msxml6.h"
40#include "msxml2did.h"
41
42#include "msxml_private.h"
43
44#include "wine/debug.h"
45
46/* This file implements the object returned by a XPath query. Note that this is
47 * not the IXMLDOMNodeList returned by childNodes - it's implemented in nodelist.c.
48 * They are different because the list returned by XPath queries:
49 * - is static - gives the results for the XML tree as it existed during the
50 * execution of the query
51 * - supports IXMLDOMSelection
52 *
53 */
54
55#ifdef HAVE_LIBXML2
56
58
59int registerNamespaces(xmlXPathContextPtr ctxt);
60xmlChar* XSLPattern_to_XPath(xmlXPathContextPtr ctxt, xmlChar const* xslpat_str);
61
62typedef struct
63{
64 IEnumVARIANT IEnumVARIANT_iface;
65 LONG ref;
66
67 IUnknown *outer;
68 BOOL own;
69
70 LONG pos;
71
72 const struct enumvariant_funcs *funcs;
74
75typedef struct
76{
77 DispatchEx dispex;
78 IXMLDOMSelection IXMLDOMSelection_iface;
79 LONG ref;
81 xmlXPathObjectPtr result;
82 int resultPos;
84} domselection;
85
86static HRESULT selection_get_item(IUnknown *iface, LONG index, VARIANT* item)
87{
89 return IXMLDOMSelection_get_item((IXMLDOMSelection*)iface, index, (IXMLDOMNode**)&V_DISPATCH(item));
90}
91
92static HRESULT selection_next(IUnknown *iface)
93{
95 HRESULT hr = IXMLDOMSelection_nextNode((IXMLDOMSelection*)iface, &node);
96 if (hr == S_OK) IXMLDOMNode_Release(node);
97 return hr;
98}
99
100static const struct enumvariant_funcs selection_enumvariant = {
101 selection_get_item,
102 selection_next
103};
104
105static inline domselection *impl_from_IXMLDOMSelection( IXMLDOMSelection *iface )
106{
107 return CONTAINING_RECORD(iface, domselection, IXMLDOMSelection_iface);
108}
109
110static inline enumvariant *impl_from_IEnumVARIANT( IEnumVARIANT *iface )
111{
112 return CONTAINING_RECORD(iface, enumvariant, IEnumVARIANT_iface);
113}
114
115static HRESULT WINAPI domselection_QueryInterface(
116 IXMLDOMSelection *iface,
117 REFIID riid,
118 void** ppvObject )
119{
120 domselection *This = impl_from_IXMLDOMSelection( iface );
121
122 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);
123
124 if(!ppvObject)
125 return E_INVALIDARG;
126
127 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
128 IsEqualGUID( riid, &IID_IXMLDOMNodeList ) ||
129 IsEqualGUID( riid, &IID_IXMLDOMSelection ))
130 {
131 *ppvObject = &This->IXMLDOMSelection_iface;
132 }
133 else if (IsEqualGUID( riid, &IID_IEnumVARIANT ))
134 {
135 if (!This->enumvariant)
136 {
137 HRESULT hr = create_enumvariant((IUnknown*)iface, FALSE, &selection_enumvariant, &This->enumvariant);
138 if (FAILED(hr)) return hr;
139 }
140
141 return IEnumVARIANT_QueryInterface(This->enumvariant, &IID_IEnumVARIANT, ppvObject);
142 }
143 else if (dispex_query_interface(&This->dispex, riid, ppvObject))
144 {
145 return *ppvObject ? S_OK : E_NOINTERFACE;
146 }
147 else
148 {
149 TRACE("interface %s not implemented\n", debugstr_guid(riid));
150 *ppvObject = NULL;
151 return E_NOINTERFACE;
152 }
153
154 IXMLDOMSelection_AddRef( iface );
155
156 return S_OK;
157}
158
159static ULONG WINAPI domselection_AddRef(
160 IXMLDOMSelection *iface )
161{
162 domselection *This = impl_from_IXMLDOMSelection( iface );
164 TRACE("(%p)->(%d)\n", This, ref);
165 return ref;
166}
167
168static ULONG WINAPI domselection_Release(
169 IXMLDOMSelection *iface )
170{
171 domselection *This = impl_from_IXMLDOMSelection( iface );
173
174 TRACE("(%p)->(%d)\n", This, ref);
175 if ( ref == 0 )
176 {
177 xmlXPathFreeObject(This->result);
178 xmldoc_release(This->node->doc);
179 if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant);
181 }
182
183 return ref;
184}
185
186static HRESULT WINAPI domselection_GetTypeInfoCount(
187 IXMLDOMSelection *iface,
188 UINT* pctinfo )
189{
190 domselection *This = impl_from_IXMLDOMSelection( iface );
191 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
192}
193
194static HRESULT WINAPI domselection_GetTypeInfo(
195 IXMLDOMSelection *iface,
196 UINT iTInfo,
197 LCID lcid,
198 ITypeInfo** ppTInfo )
199{
200 domselection *This = impl_from_IXMLDOMSelection( iface );
201 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
202 iTInfo, lcid, ppTInfo);
203}
204
205static HRESULT WINAPI domselection_GetIDsOfNames(
206 IXMLDOMSelection *iface,
207 REFIID riid,
208 LPOLESTR* rgszNames,
209 UINT cNames,
210 LCID lcid,
211 DISPID* rgDispId )
212{
213 domselection *This = impl_from_IXMLDOMSelection( iface );
214 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
215 riid, rgszNames, cNames, lcid, rgDispId);
216}
217
218static HRESULT WINAPI domselection_Invoke(
219 IXMLDOMSelection *iface,
220 DISPID dispIdMember,
221 REFIID riid,
222 LCID lcid,
223 WORD wFlags,
224 DISPPARAMS* pDispParams,
225 VARIANT* pVarResult,
226 EXCEPINFO* pExcepInfo,
227 UINT* puArgErr )
228{
229 domselection *This = impl_from_IXMLDOMSelection( iface );
230 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
231 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
232}
233
234static HRESULT WINAPI domselection_get_item(
235 IXMLDOMSelection* iface,
236 LONG index,
237 IXMLDOMNode** listItem)
238{
239 domselection *This = impl_from_IXMLDOMSelection( iface );
240
241 TRACE("(%p)->(%d %p)\n", This, index, listItem);
242
243 if(!listItem)
244 return E_INVALIDARG;
245
246 *listItem = NULL;
247
248 if (index < 0 || index >= xmlXPathNodeSetGetLength(This->result->nodesetval))
249 return S_FALSE;
250
251 *listItem = create_node(xmlXPathNodeSetItem(This->result->nodesetval, index));
252 This->resultPos = index + 1;
253
254 return S_OK;
255}
256
257static HRESULT WINAPI domselection_get_length(
258 IXMLDOMSelection* iface,
259 LONG* listLength)
260{
261 domselection *This = impl_from_IXMLDOMSelection( iface );
262
263 TRACE("(%p)->(%p)\n", This, listLength);
264
265 if(!listLength)
266 return E_INVALIDARG;
267
268 *listLength = xmlXPathNodeSetGetLength(This->result->nodesetval);
269 return S_OK;
270}
271
272static HRESULT WINAPI domselection_nextNode(
273 IXMLDOMSelection* iface,
274 IXMLDOMNode** nextItem)
275{
276 domselection *This = impl_from_IXMLDOMSelection( iface );
277
278 TRACE("(%p)->(%p)\n", This, nextItem );
279
280 if(!nextItem)
281 return E_INVALIDARG;
282
283 *nextItem = NULL;
284
285 if (This->resultPos >= xmlXPathNodeSetGetLength(This->result->nodesetval))
286 return S_FALSE;
287
288 *nextItem = create_node(xmlXPathNodeSetItem(This->result->nodesetval, This->resultPos));
289 This->resultPos++;
290 return S_OK;
291}
292
293static HRESULT WINAPI domselection_reset(
294 IXMLDOMSelection* iface)
295{
296 domselection *This = impl_from_IXMLDOMSelection( iface );
297
298 TRACE("%p\n", This);
299 This->resultPos = 0;
300 return S_OK;
301}
302
303static HRESULT WINAPI domselection_get__newEnum(
304 IXMLDOMSelection* iface,
305 IUnknown** enumv)
306{
307 domselection *This = impl_from_IXMLDOMSelection( iface );
308
309 TRACE("(%p)->(%p)\n", This, enumv);
310
311 return create_enumvariant((IUnknown*)iface, TRUE, &selection_enumvariant, (IEnumVARIANT**)enumv);
312}
313
314static HRESULT WINAPI domselection_get_expr(
315 IXMLDOMSelection* iface,
316 BSTR *p)
317{
318 domselection *This = impl_from_IXMLDOMSelection( iface );
319 FIXME("(%p)->(%p)\n", This, p);
320 return E_NOTIMPL;
321}
322
323static HRESULT WINAPI domselection_put_expr(
324 IXMLDOMSelection* iface,
325 BSTR p)
326{
327 domselection *This = impl_from_IXMLDOMSelection( iface );
328 FIXME("(%p)->(%s)\n", This, debugstr_w(p));
329 return E_NOTIMPL;
330}
331
332static HRESULT WINAPI domselection_get_context(
333 IXMLDOMSelection* iface,
335{
336 domselection *This = impl_from_IXMLDOMSelection( iface );
337 FIXME("(%p)->(%p)\n", This, node);
338 return E_NOTIMPL;
339}
340
341static HRESULT WINAPI domselection_putref_context(
342 IXMLDOMSelection* iface,
344{
345 domselection *This = impl_from_IXMLDOMSelection( iface );
346 FIXME("(%p)->(%p)\n", This, node);
347 return E_NOTIMPL;
348}
349
350static HRESULT WINAPI domselection_peekNode(
351 IXMLDOMSelection* iface,
353{
354 domselection *This = impl_from_IXMLDOMSelection( iface );
355 FIXME("(%p)->(%p)\n", This, node);
356 return E_NOTIMPL;
357}
358
359static HRESULT WINAPI domselection_matches(
360 IXMLDOMSelection* iface,
362 IXMLDOMNode **out_node)
363{
364 domselection *This = impl_from_IXMLDOMSelection( iface );
365 FIXME("(%p)->(%p %p)\n", This, node, out_node);
366 return E_NOTIMPL;
367}
368
369static HRESULT WINAPI domselection_removeNext(
370 IXMLDOMSelection* iface,
372{
373 domselection *This = impl_from_IXMLDOMSelection( iface );
374 FIXME("(%p)->(%p)\n", This, node);
375 return E_NOTIMPL;
376}
377
378static HRESULT WINAPI domselection_removeAll(
379 IXMLDOMSelection* iface)
380{
381 domselection *This = impl_from_IXMLDOMSelection( iface );
382 FIXME("(%p)\n", This);
383 return E_NOTIMPL;
384}
385
386static HRESULT WINAPI domselection_clone(
387 IXMLDOMSelection* iface,
388 IXMLDOMSelection **node)
389{
390 domselection *This = impl_from_IXMLDOMSelection( iface );
391 FIXME("(%p)->(%p)\n", This, node);
392 return E_NOTIMPL;
393}
394
395static HRESULT WINAPI domselection_getProperty(
396 IXMLDOMSelection* iface,
397 BSTR p,
398 VARIANT *var)
399{
400 domselection *This = impl_from_IXMLDOMSelection( iface );
401 FIXME("(%p)->(%s %p)\n", This, debugstr_w(p), var);
402 return E_NOTIMPL;
403}
404
405static HRESULT WINAPI domselection_setProperty(
406 IXMLDOMSelection* iface,
407 BSTR p,
408 VARIANT var)
409{
410 domselection *This = impl_from_IXMLDOMSelection( iface );
411 FIXME("(%p)->(%s %s)\n", This, debugstr_w(p), debugstr_variant(&var));
412 return E_NOTIMPL;
413}
414
415static const struct IXMLDOMSelectionVtbl domselection_vtbl =
416{
417 domselection_QueryInterface,
418 domselection_AddRef,
419 domselection_Release,
420 domselection_GetTypeInfoCount,
421 domselection_GetTypeInfo,
422 domselection_GetIDsOfNames,
423 domselection_Invoke,
424 domselection_get_item,
425 domselection_get_length,
426 domselection_nextNode,
427 domselection_reset,
428 domselection_get__newEnum,
429 domselection_get_expr,
430 domselection_put_expr,
431 domselection_get_context,
432 domselection_putref_context,
433 domselection_peekNode,
434 domselection_matches,
435 domselection_removeNext,
436 domselection_removeAll,
437 domselection_clone,
438 domselection_getProperty,
439 domselection_setProperty
440};
441
442/* IEnumVARIANT support */
444 IEnumVARIANT *iface,
445 REFIID riid,
446 void** ppvObject )
447{
449
450 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
451
452 *ppvObject = NULL;
453
455 {
456 if (This->own)
457 *ppvObject = &This->IEnumVARIANT_iface;
458 else
459 return IUnknown_QueryInterface(This->outer, riid, ppvObject);
460 }
461 else if (IsEqualGUID( riid, &IID_IEnumVARIANT ))
462 {
463 *ppvObject = &This->IEnumVARIANT_iface;
464 }
465 else
466 return IUnknown_QueryInterface(This->outer, riid, ppvObject);
467
468 IEnumVARIANT_AddRef( iface );
469
470 return S_OK;
471}
472
474{
477 TRACE("(%p)->(%d)\n", This, ref);
478 return ref;
479}
480
481static ULONG WINAPI enumvariant_Release(IEnumVARIANT *iface )
482{
485
486 TRACE("(%p)->(%d)\n", This, ref);
487 if ( ref == 0 )
488 {
489 if (This->own) IUnknown_Release(This->outer);
491 }
492
493 return ref;
494}
495
496static HRESULT WINAPI enumvariant_Next(
497 IEnumVARIANT *iface,
498 ULONG celt,
499 VARIANT *var,
500 ULONG *fetched)
501{
503 ULONG ret_count = 0;
504
505 TRACE("(%p)->(%u %p %p)\n", This, celt, var, fetched);
506
507 if (fetched) *fetched = 0;
508
509 if (celt && !var) return E_INVALIDARG;
510
511 for (; celt > 0; celt--, var++, This->pos++)
512 {
513 HRESULT hr = This->funcs->get_item(This->outer, This->pos, var);
514 if (hr != S_OK)
515 {
516 V_VT(var) = VT_EMPTY;
517 break;
518 }
519 ret_count++;
520 }
521
522 if (fetched) (*fetched)++;
523
524 /* we need to advance one step more for some reason */
525 if (ret_count)
526 {
527 if (This->funcs->next)
528 This->funcs->next(This->outer);
529 }
530
531 return celt == 0 ? S_OK : S_FALSE;
532}
533
534static HRESULT WINAPI enumvariant_Skip(
535 IEnumVARIANT *iface,
536 ULONG celt)
537{
539 FIXME("(%p)->(%u): stub\n", This, celt);
540 return E_NOTIMPL;
541}
542
543static HRESULT WINAPI enumvariant_Reset(IEnumVARIANT *iface)
544{
546 FIXME("(%p): stub\n", This);
547 return E_NOTIMPL;
548}
549
550static HRESULT WINAPI enumvariant_Clone(
551 IEnumVARIANT *iface, IEnumVARIANT **ppenum)
552{
554 FIXME("(%p)->(%p): stub\n", This, ppenum);
555 return E_NOTIMPL;
556}
557
558static const struct IEnumVARIANTVtbl EnumVARIANTVtbl =
559{
562 enumvariant_Release,
563 enumvariant_Next,
564 enumvariant_Skip,
565 enumvariant_Reset,
566 enumvariant_Clone
567};
568
569HRESULT create_enumvariant(IUnknown *outer, BOOL own, const struct enumvariant_funcs *funcs, IEnumVARIANT **penum)
570{
572
573 This = heap_alloc(sizeof(enumvariant));
574 if (!This) return E_OUTOFMEMORY;
575
576 This->IEnumVARIANT_iface.lpVtbl = &EnumVARIANTVtbl;
577 This->ref = 0;
578 This->outer = outer;
579 This->own = own;
580 This->pos = 0;
581 This->funcs = funcs;
582
583 if (This->own)
584 IUnknown_AddRef(This->outer);
585
586 *penum = &This->IEnumVARIANT_iface;
587 IEnumVARIANT_AddRef(*penum);
588 return S_OK;
589}
590
591static HRESULT domselection_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid)
592{
593 WCHAR *ptr;
594 int idx = 0;
595
596 for(ptr = name; *ptr && isdigitW(*ptr); ptr++)
597 idx = idx*10 + (*ptr-'0');
598 if(*ptr)
599 return DISP_E_UNKNOWNNAME;
600
602 TRACE("ret %x\n", *dispid);
603 return S_OK;
604}
605
606static HRESULT domselection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
607 VARIANT *res, EXCEPINFO *ei)
608{
609 domselection *This = impl_from_IXMLDOMSelection( (IXMLDOMSelection*)iface );
610
611 TRACE("(%p)->(%x %x %x %p %p %p)\n", This, id, lcid, flags, params, res, ei);
612
615
616 if (id < DISPID_DOM_COLLECTION_BASE || id > DISPID_DOM_COLLECTION_MAX)
617 return DISP_E_UNKNOWNNAME;
618
619 switch(flags)
620 {
621 case INVOKE_PROPERTYGET:
622 {
623 IXMLDOMNode *disp = NULL;
624
625 IXMLDOMSelection_get_item(&This->IXMLDOMSelection_iface, id - DISPID_DOM_COLLECTION_BASE, &disp);
626 V_DISPATCH(res) = (IDispatch*)disp;
627 break;
628 }
629 default:
630 {
631 FIXME("unimplemented flags %x\n", flags);
632 break;
633 }
634 }
635
636 TRACE("ret %p\n", V_DISPATCH(res));
637
638 return S_OK;
639}
640
641static const dispex_static_data_vtbl_t domselection_dispex_vtbl = {
642 domselection_get_dispid,
643 domselection_invoke
644};
645
646static const tid_t domselection_iface_tids[] = {
648 0
649};
650static dispex_static_data_t domselection_dispex = {
651 &domselection_dispex_vtbl,
653 NULL,
654 domselection_iface_tids
655};
656
657#define XSLPATTERN_CHECK_ARGS(n) \
658 if (nargs != n) { \
659 FIXME("XSLPattern syntax error: Expected %i arguments, got %i\n", n, nargs); \
660 xmlXPathSetArityError(pctx); \
661 return; \
662 }
663
664
665static void XSLPattern_index(xmlXPathParserContextPtr pctx, int nargs)
666{
667 XSLPATTERN_CHECK_ARGS(0);
668
669 xmlXPathPositionFunction(pctx, 0);
670 xmlXPathReturnNumber(pctx, xmlXPathPopNumber(pctx) - 1.0);
671}
672
673static void XSLPattern_end(xmlXPathParserContextPtr pctx, int nargs)
674{
675 double pos, last;
676 XSLPATTERN_CHECK_ARGS(0);
677
678 xmlXPathPositionFunction(pctx, 0);
679 pos = xmlXPathPopNumber(pctx);
680 xmlXPathLastFunction(pctx, 0);
681 last = xmlXPathPopNumber(pctx);
682 xmlXPathReturnBoolean(pctx, pos == last);
683}
684
685static void XSLPattern_nodeType(xmlXPathParserContextPtr pctx, int nargs)
686{
687 XSLPATTERN_CHECK_ARGS(0);
688 xmlXPathReturnNumber(pctx, pctx->context->node->type);
689}
690
691static void XSLPattern_OP_IEq(xmlXPathParserContextPtr pctx, int nargs)
692{
693 xmlChar *arg1, *arg2;
694 XSLPATTERN_CHECK_ARGS(2);
695
696 arg2 = xmlXPathPopString(pctx);
697 arg1 = xmlXPathPopString(pctx);
698 xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) == 0);
699 xmlFree(arg1);
700 xmlFree(arg2);
701}
702
703static void XSLPattern_OP_INEq(xmlXPathParserContextPtr pctx, int nargs)
704{
705 xmlChar *arg1, *arg2;
706 XSLPATTERN_CHECK_ARGS(2);
707
708 arg2 = xmlXPathPopString(pctx);
709 arg1 = xmlXPathPopString(pctx);
710 xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) != 0);
711 xmlFree(arg1);
712 xmlFree(arg2);
713}
714
715static void XSLPattern_OP_ILt(xmlXPathParserContextPtr pctx, int nargs)
716{
717 xmlChar *arg1, *arg2;
718 XSLPATTERN_CHECK_ARGS(2);
719
720 arg2 = xmlXPathPopString(pctx);
721 arg1 = xmlXPathPopString(pctx);
722 xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) < 0);
723 xmlFree(arg1);
724 xmlFree(arg2);
725}
726
727static void XSLPattern_OP_ILEq(xmlXPathParserContextPtr pctx, int nargs)
728{
729 xmlChar *arg1, *arg2;
730 XSLPATTERN_CHECK_ARGS(2);
731
732 arg2 = xmlXPathPopString(pctx);
733 arg1 = xmlXPathPopString(pctx);
734 xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) <= 0);
735 xmlFree(arg1);
736 xmlFree(arg2);
737}
738
739static void XSLPattern_OP_IGt(xmlXPathParserContextPtr pctx, int nargs)
740{
741 xmlChar *arg1, *arg2;
742 XSLPATTERN_CHECK_ARGS(2);
743
744 arg2 = xmlXPathPopString(pctx);
745 arg1 = xmlXPathPopString(pctx);
746 xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) > 0);
747 xmlFree(arg1);
748 xmlFree(arg2);
749}
750
751static void XSLPattern_OP_IGEq(xmlXPathParserContextPtr pctx, int nargs)
752{
753 xmlChar *arg1, *arg2;
754 XSLPATTERN_CHECK_ARGS(2);
755
756 arg2 = xmlXPathPopString(pctx);
757 arg1 = xmlXPathPopString(pctx);
758 xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) >= 0);
759 xmlFree(arg1);
760 xmlFree(arg2);
761}
762
763static void query_serror(void* ctx, xmlErrorPtr err)
764{
765 LIBXML2_CALLBACK_SERROR(domselection_create, err);
766}
767
769{
770 domselection *This = heap_alloc(sizeof(domselection));
771 xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc);
772 HRESULT hr;
773
774 TRACE("(%p, %s, %p)\n", node, debugstr_a((char const*)query), out);
775
776 *out = NULL;
777 if (!This || !ctxt || !query)
778 {
779 xmlXPathFreeContext(ctxt);
781 return E_OUTOFMEMORY;
782 }
783
784 This->IXMLDOMSelection_iface.lpVtbl = &domselection_vtbl;
785 This->ref = 1;
786 This->resultPos = 0;
787 This->node = node;
788 This->enumvariant = NULL;
789 init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMSelection_iface, &domselection_dispex);
790 xmldoc_add_ref(This->node->doc);
791
792 ctxt->error = query_serror;
793 ctxt->node = node;
794 registerNamespaces(ctxt);
795
796 if (is_xpathmode(This->node->doc))
797 {
798 xmlXPathRegisterAllFunctions(ctxt);
799 This->result = xmlXPathEvalExpression(query, ctxt);
800 }
801 else
802 {
803 xmlChar* pattern_query = XSLPattern_to_XPath(ctxt, query);
804
805 xmlXPathRegisterFunc(ctxt, (xmlChar const*)"not", xmlXPathNotFunction);
806 xmlXPathRegisterFunc(ctxt, (xmlChar const*)"boolean", xmlXPathBooleanFunction);
807
808 xmlXPathRegisterFunc(ctxt, (xmlChar const*)"index", XSLPattern_index);
809 xmlXPathRegisterFunc(ctxt, (xmlChar const*)"end", XSLPattern_end);
810 xmlXPathRegisterFunc(ctxt, (xmlChar const*)"nodeType", XSLPattern_nodeType);
811
812 xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IEq", XSLPattern_OP_IEq);
813 xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_INEq", XSLPattern_OP_INEq);
814 xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILt", XSLPattern_OP_ILt);
815 xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILEq", XSLPattern_OP_ILEq);
816 xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGt", XSLPattern_OP_IGt);
817 xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGEq", XSLPattern_OP_IGEq);
818
819 This->result = xmlXPathEvalExpression(pattern_query, ctxt);
820 xmlFree(pattern_query);
821 }
822
823 if (!This->result || This->result->type != XPATH_NODESET)
824 {
825 hr = E_FAIL;
826 goto cleanup;
827 }
828
829 *out = (IXMLDOMNodeList*)&This->IXMLDOMSelection_iface;
830 hr = S_OK;
831 TRACE("found %d matches\n", xmlXPathNodeSetGetLength(This->result->nodesetval));
832
833cleanup:
834 if (FAILED(hr))
835 IXMLDOMSelection_Release( &This->IXMLDOMSelection_iface );
836 xmlXPathFreeContext(ctxt);
837 return hr;
838}
839
840#endif
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
OLECHAR * BSTR
Definition: compat.h:2293
@ VT_EMPTY
Definition: compat.h:2295
@ VT_DISPATCH
Definition: compat.h:2304
static void cleanup(void)
Definition: main.c:1335
static HRESULT WINAPI enumvariant_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **obj)
Definition: filesystem.c:1145
static ULONG WINAPI enumvariant_AddRef(IEnumVARIANT *iface)
Definition: filesystem.c:1165
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint res
Definition: glext.h:9613
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLuint index
Definition: glext.h:6031
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLenum const GLfloat * params
Definition: glext.h:5645
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLuint64EXT * result
Definition: glext.h:11304
static HTMLElementCollectionEnum * impl_from_IEnumVARIANT(IEnumVARIANT *iface)
Definition: htmlelemcol.c:85
static HRESULT create_node(HTMLDocumentNode *, nsIDOMNode *, HTMLDOMNode **)
Definition: htmlnode.c:1216
tid_t
Definition: ieframe.h:311
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:919
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
static PVOID ptr
Definition: dispmode.c:27
const char * var
Definition: shader.c:5666
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
static UINT UINT last
Definition: font.c:45
static LPOLESTR
Definition: stg_prop.c:27
static VARIANTARG static DISPID
Definition: ordinal.c:52
static ATOM item
Definition: dde.c:856
static const IEnumVARIANTVtbl EnumVARIANTVtbl
Definition: run.c:664
BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
Definition: dispex.c:1656
#define DISPID_DOM_COLLECTION_MAX
Definition: msxml2did.h:71
#define DISPID_DOM_COLLECTION_BASE
Definition: msxml2did.h:70
@ IXMLDOMSelection_tid
Definition: msxml_private.h:64
unsigned int UINT
Definition: ndis.h:50
#define V_VT(A)
Definition: oleauto.h:211
#define V_DISPATCH(A)
Definition: oleauto.h:239
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define isdigitW(n)
Definition: unicode.h:50
#define err(...)
static FILE * out
Definition: regtests2xml.c:44
DWORD LCID
Definition: nls.h:13
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
static struct __wine_debug_functions funcs
Definition: debug.c:59
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
Definition: tree.h:489
Definition: name.c:39
Definition: send.c:48
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: dlist.c:348
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
__wchar_t WCHAR
Definition: xmlstorage.h:180
XMLPUBFUN int XMLCALL xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:275
unsigned char xmlChar
Definition: xmlstring.h:28