msxml4/tests: Copy namespaces as attributes tests.
[wine.git] / dlls / msxml3 / pi.c
blob719222bd9adb2c4df50fdd4b1691c1221531218e
1 /*
2 * DOM processing instruction node implementation
4 * Copyright 2006 Huw Davies
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
21 #define COBJMACROS
23 #include <stdarg.h>
24 #include <libxml/parser.h>
25 #include <libxml/xmlerror.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "ole2.h"
31 #include "msxml6.h"
33 #include "xmlparser.h"
34 #include "msxml_private.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
40 typedef struct _dom_pi
42 xmlnode node;
43 IXMLDOMProcessingInstruction IXMLDOMProcessingInstruction_iface;
44 LONG ref;
45 } dom_pi;
47 static const struct nodemap_funcs dom_pi_attr_map;
49 static const tid_t dompi_se_tids[] = {
50 IXMLDOMNode_tid,
51 IXMLDOMProcessingInstruction_tid,
52 NULL_tid
55 static inline dom_pi *impl_from_IXMLDOMProcessingInstruction( IXMLDOMProcessingInstruction *iface )
57 return CONTAINING_RECORD(iface, dom_pi, IXMLDOMProcessingInstruction_iface);
60 static HRESULT WINAPI dom_pi_QueryInterface(
61 IXMLDOMProcessingInstruction *iface,
62 REFIID riid,
63 void** ppvObject )
65 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
66 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
68 if ( IsEqualGUID( riid, &IID_IXMLDOMProcessingInstruction ) ||
69 IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
70 IsEqualGUID( riid, &IID_IDispatch ) ||
71 IsEqualGUID( riid, &IID_IUnknown ) )
73 *ppvObject = iface;
75 else if(node_query_interface(&This->node, riid, ppvObject))
77 return *ppvObject ? S_OK : E_NOINTERFACE;
79 else if(IsEqualGUID( riid, &IID_ISupportErrorInfo ))
81 return node_create_supporterrorinfo(dompi_se_tids, ppvObject);
83 else
85 TRACE("Unsupported interface %s\n", debugstr_guid(riid));
86 *ppvObject = NULL;
87 return E_NOINTERFACE;
90 IUnknown_AddRef((IUnknown*)*ppvObject);
91 return S_OK;
94 static ULONG WINAPI dom_pi_AddRef(
95 IXMLDOMProcessingInstruction *iface )
97 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
98 ULONG ref = InterlockedIncrement( &This->ref );
99 TRACE("%p, refcount %lu.\n", iface, ref);
100 return ref;
103 static ULONG WINAPI dom_pi_Release(
104 IXMLDOMProcessingInstruction *iface )
106 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
107 ULONG ref = InterlockedDecrement( &This->ref );
109 TRACE("%p, refcount %lu.\n", iface, ref);
110 if ( ref == 0 )
112 destroy_xmlnode(&This->node);
113 heap_free( This );
116 return ref;
119 static HRESULT WINAPI dom_pi_GetTypeInfoCount(
120 IXMLDOMProcessingInstruction *iface,
121 UINT* pctinfo )
123 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
124 return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo);
127 static HRESULT WINAPI dom_pi_GetTypeInfo(
128 IXMLDOMProcessingInstruction *iface,
129 UINT iTInfo, LCID lcid,
130 ITypeInfo** ppTInfo )
132 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
133 return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface,
134 iTInfo, lcid, ppTInfo);
137 static HRESULT WINAPI dom_pi_GetIDsOfNames(
138 IXMLDOMProcessingInstruction *iface,
139 REFIID riid, LPOLESTR* rgszNames,
140 UINT cNames, LCID lcid, DISPID* rgDispId )
142 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
143 return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface,
144 riid, rgszNames, cNames, lcid, rgDispId);
147 static HRESULT WINAPI dom_pi_Invoke(
148 IXMLDOMProcessingInstruction *iface,
149 DISPID dispIdMember, REFIID riid, LCID lcid,
150 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
151 EXCEPINFO* pExcepInfo, UINT* puArgErr )
153 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
154 return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface,
155 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
158 static HRESULT WINAPI dom_pi_get_nodeName(
159 IXMLDOMProcessingInstruction *iface,
160 BSTR* p )
162 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
164 TRACE("(%p)->(%p)\n", This, p);
166 return node_get_nodeName(&This->node, p);
169 static HRESULT WINAPI dom_pi_get_nodeValue(
170 IXMLDOMProcessingInstruction *iface,
171 VARIANT* value)
173 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
175 TRACE("(%p)->(%p)\n", This, value);
177 return node_get_content(&This->node, value);
180 static HRESULT WINAPI dom_pi_put_nodeValue(
181 IXMLDOMProcessingInstruction *iface,
182 VARIANT value)
184 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
185 BSTR target;
186 HRESULT hr;
188 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
190 /* Cannot set data to a PI node whose target is 'xml' */
191 hr = IXMLDOMProcessingInstruction_get_nodeName(iface, &target);
192 if(hr == S_OK)
194 static const WCHAR xmlW[] = {'x','m','l',0};
195 if(!wcscmp(target, xmlW))
197 SysFreeString(target);
198 return E_FAIL;
201 SysFreeString(target);
204 return node_put_value(&This->node, &value);
207 static HRESULT WINAPI dom_pi_get_nodeType(
208 IXMLDOMProcessingInstruction *iface,
209 DOMNodeType* domNodeType )
211 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
213 TRACE("(%p)->(%p)\n", This, domNodeType);
215 *domNodeType = NODE_PROCESSING_INSTRUCTION;
216 return S_OK;
219 static HRESULT WINAPI dom_pi_get_parentNode(
220 IXMLDOMProcessingInstruction *iface,
221 IXMLDOMNode** parent )
223 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
225 TRACE("(%p)->(%p)\n", This, parent);
227 return node_get_parent(&This->node, parent);
230 static HRESULT WINAPI dom_pi_get_childNodes(
231 IXMLDOMProcessingInstruction *iface,
232 IXMLDOMNodeList** outList)
234 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
236 TRACE("(%p)->(%p)\n", This, outList);
238 return node_get_child_nodes(&This->node, outList);
241 static HRESULT WINAPI dom_pi_get_firstChild(
242 IXMLDOMProcessingInstruction *iface,
243 IXMLDOMNode** domNode)
245 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
247 TRACE("(%p)->(%p)\n", This, domNode);
249 return return_null_node(domNode);
252 static HRESULT WINAPI dom_pi_get_lastChild(
253 IXMLDOMProcessingInstruction *iface,
254 IXMLDOMNode** domNode)
256 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
258 TRACE("(%p)->(%p)\n", This, domNode);
260 return return_null_node(domNode);
263 static HRESULT WINAPI dom_pi_get_previousSibling(
264 IXMLDOMProcessingInstruction *iface,
265 IXMLDOMNode** domNode)
267 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
269 TRACE("(%p)->(%p)\n", This, domNode);
271 return node_get_previous_sibling(&This->node, domNode);
274 static HRESULT WINAPI dom_pi_get_nextSibling(
275 IXMLDOMProcessingInstruction *iface,
276 IXMLDOMNode** domNode)
278 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
280 TRACE("(%p)->(%p)\n", This, domNode);
282 return node_get_next_sibling(&This->node, domNode);
285 static HRESULT xml_get_value(xmlChar **p, xmlChar **value)
287 xmlChar *v, q;
288 int len;
290 while (isspace(**p)) *p += 1;
291 if (**p != '=') return XML_E_MISSINGEQUALS;
292 *p += 1;
294 while (isspace(**p)) *p += 1;
295 if (**p != '"' && **p != '\'') return XML_E_MISSINGQUOTE;
296 q = **p;
297 *p += 1;
299 v = *p;
300 while (**p && **p != q) *p += 1;
301 if (!**p) return XML_E_BADCHARINSTRING;
302 len = *p - v;
303 if (!len) return XML_E_MISSINGNAME;
304 *p += 1;
306 *value = heap_alloc(len + 1);
307 if (!*value) return E_OUTOFMEMORY;
308 memcpy(*value, v, len);
309 *(*value + len) = 0;
311 return S_OK;
314 static void set_prop(xmlNodePtr node, xmlAttrPtr attr)
316 xmlAttrPtr prop;
318 if (!node->properties)
320 node->properties = attr;
321 return;
324 prop = node->properties;
325 while (prop->next) prop = prop->next;
327 prop->next = attr;
330 static HRESULT parse_xml_decl(xmlNodePtr node)
332 xmlChar *version, *encoding, *standalone, *p;
333 xmlAttrPtr attr;
334 HRESULT hr = S_OK;
336 if (!node->content) return S_OK;
338 version = encoding = standalone = NULL;
340 p = node->content;
342 while (*p)
344 while (isspace(*p)) p++;
345 if (!*p) break;
347 if (!strncmp((const char *)p, "version", 7))
349 p += 7;
350 if ((hr = xml_get_value(&p, &version)) != S_OK) goto fail;
352 else if (!strncmp((const char *)p, "encoding", 8))
354 p += 8;
355 if ((hr = xml_get_value(&p, &encoding)) != S_OK) goto fail;
357 else if (!strncmp((const char *)p, "standalone", 10))
359 p += 10;
360 if ((hr = xml_get_value(&p, &standalone)) != S_OK) goto fail;
362 else
364 FIXME("unexpected XML attribute %s\n", debugstr_a((const char *)p));
365 hr = XML_E_UNEXPECTED_ATTRIBUTE;
366 goto fail;
370 /* xmlSetProp/xmlSetNsProp accept only nodes of type XML_ELEMENT_NODE,
371 * so we have to create and assign attributes to a node by hand.
374 if (version)
376 attr = xmlSetNsProp(NULL, NULL, (const xmlChar *)"version", version);
377 if (attr)
379 attr->doc = node->doc;
380 set_prop(node, attr);
382 else hr = E_OUTOFMEMORY;
384 if (encoding)
386 attr = xmlSetNsProp(NULL, NULL, (const xmlChar *)"encoding", encoding);
387 if (attr)
389 attr->doc = node->doc;
390 set_prop(node, attr);
392 else hr = E_OUTOFMEMORY;
394 if (standalone)
396 attr = xmlSetNsProp(NULL, NULL, (const xmlChar *)"standalone", standalone);
397 if (attr)
399 attr->doc = node->doc;
400 set_prop(node, attr);
402 else hr = E_OUTOFMEMORY;
405 fail:
406 if (hr != S_OK)
408 xmlFreePropList(node->properties);
409 node->properties = NULL;
412 heap_free(version);
413 heap_free(encoding);
414 heap_free(standalone);
415 return hr;
418 static HRESULT WINAPI dom_pi_get_attributes(
419 IXMLDOMProcessingInstruction *iface,
420 IXMLDOMNamedNodeMap** map)
422 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
423 static const WCHAR xmlW[] = {'x','m','l',0};
424 HRESULT hr;
425 BSTR name;
427 TRACE("(%p)->(%p)\n", This, map);
429 if (!map) return E_INVALIDARG;
431 *map = NULL;
433 hr = node_get_nodeName(&This->node, &name);
434 if (hr != S_OK) return hr;
436 if (!wcscmp(name, xmlW))
437 *map = create_nodemap(This->node.node, &dom_pi_attr_map);
439 SysFreeString(name);
441 return *map ? S_OK : S_FALSE;
444 static HRESULT WINAPI dom_pi_insertBefore(
445 IXMLDOMProcessingInstruction *iface,
446 IXMLDOMNode* newNode, VARIANT refChild,
447 IXMLDOMNode** outOldNode)
449 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
451 FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode);
453 return node_insert_before(&This->node, newNode, &refChild, outOldNode);
456 static HRESULT WINAPI dom_pi_replaceChild(
457 IXMLDOMProcessingInstruction *iface,
458 IXMLDOMNode* newNode,
459 IXMLDOMNode* oldNode,
460 IXMLDOMNode** outOldNode)
462 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
464 FIXME("(%p)->(%p %p %p) needs test\n", This, newNode, oldNode, outOldNode);
466 return node_replace_child(&This->node, newNode, oldNode, outOldNode);
469 static HRESULT WINAPI dom_pi_removeChild(
470 IXMLDOMProcessingInstruction *iface,
471 IXMLDOMNode *child, IXMLDOMNode **oldChild)
473 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
474 TRACE("(%p)->(%p %p)\n", This, child, oldChild);
475 return node_remove_child(&This->node, child, oldChild);
478 static HRESULT WINAPI dom_pi_appendChild(
479 IXMLDOMProcessingInstruction *iface,
480 IXMLDOMNode *child, IXMLDOMNode **outChild)
482 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
483 TRACE("(%p)->(%p %p)\n", This, child, outChild);
484 return node_append_child(&This->node, child, outChild);
487 static HRESULT WINAPI dom_pi_hasChildNodes(
488 IXMLDOMProcessingInstruction *iface,
489 VARIANT_BOOL *ret)
491 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
492 TRACE("(%p)->(%p)\n", This, ret);
493 return node_has_childnodes(&This->node, ret);
496 static HRESULT WINAPI dom_pi_get_ownerDocument(
497 IXMLDOMProcessingInstruction *iface,
498 IXMLDOMDocument **doc)
500 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
501 TRACE("(%p)->(%p)\n", This, doc);
502 return node_get_owner_doc(&This->node, doc);
505 static HRESULT WINAPI dom_pi_cloneNode(
506 IXMLDOMProcessingInstruction *iface,
507 VARIANT_BOOL deep, IXMLDOMNode** outNode)
509 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
510 TRACE("(%p)->(%d %p)\n", This, deep, outNode);
511 return node_clone( &This->node, deep, outNode );
514 static HRESULT WINAPI dom_pi_get_nodeTypeString(
515 IXMLDOMProcessingInstruction *iface,
516 BSTR* p)
518 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
519 static const WCHAR processinginstructionW[] =
520 {'p','r','o','c','e','s','s','i','n','g','i','n','s','t','r','u','c','t','i','o','n',0};
522 TRACE("(%p)->(%p)\n", This, p);
524 return return_bstr(processinginstructionW, p);
527 static HRESULT WINAPI dom_pi_get_text(
528 IXMLDOMProcessingInstruction *iface,
529 BSTR* p)
531 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
532 TRACE("(%p)->(%p)\n", This, p);
533 return node_get_text(&This->node, p);
536 static HRESULT WINAPI dom_pi_put_text(
537 IXMLDOMProcessingInstruction *iface,
538 BSTR p)
540 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
541 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
542 return node_put_text( &This->node, p );
545 static HRESULT WINAPI dom_pi_get_specified(
546 IXMLDOMProcessingInstruction *iface,
547 VARIANT_BOOL* isSpecified)
549 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
550 FIXME("(%p)->(%p) stub!\n", This, isSpecified);
551 *isSpecified = VARIANT_TRUE;
552 return S_OK;
555 static HRESULT WINAPI dom_pi_get_definition(
556 IXMLDOMProcessingInstruction *iface,
557 IXMLDOMNode** definitionNode)
559 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
560 FIXME("(%p)->(%p)\n", This, definitionNode);
561 return E_NOTIMPL;
564 static HRESULT WINAPI dom_pi_get_nodeTypedValue(
565 IXMLDOMProcessingInstruction *iface,
566 VARIANT* v)
568 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
569 TRACE("(%p)->(%p)\n", This, v);
570 return node_get_content(&This->node, v);
573 static HRESULT WINAPI dom_pi_put_nodeTypedValue(
574 IXMLDOMProcessingInstruction *iface,
575 VARIANT typedValue)
577 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
578 FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue));
579 return E_NOTIMPL;
582 static HRESULT WINAPI dom_pi_get_dataType(
583 IXMLDOMProcessingInstruction *iface,
584 VARIANT* typename)
586 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
587 TRACE("(%p)->(%p)\n", This, typename);
588 return return_null_var( typename );
591 static HRESULT WINAPI dom_pi_put_dataType(
592 IXMLDOMProcessingInstruction *iface,
593 BSTR p)
595 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
597 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
599 if(!p)
600 return E_INVALIDARG;
602 return E_FAIL;
605 static HRESULT WINAPI dom_pi_get_xml(
606 IXMLDOMProcessingInstruction *iface,
607 BSTR* p)
609 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
611 TRACE("(%p)->(%p)\n", This, p);
613 return node_get_xml(&This->node, FALSE, p);
616 static HRESULT WINAPI dom_pi_transformNode(
617 IXMLDOMProcessingInstruction *iface,
618 IXMLDOMNode *node, BSTR *p)
620 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
621 TRACE("(%p)->(%p %p)\n", This, node, p);
622 return node_transform_node(&This->node, node, p);
625 static HRESULT WINAPI dom_pi_selectNodes(
626 IXMLDOMProcessingInstruction *iface,
627 BSTR p, IXMLDOMNodeList** outList)
629 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
630 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList);
631 return node_select_nodes(&This->node, p, outList);
634 static HRESULT WINAPI dom_pi_selectSingleNode(
635 IXMLDOMProcessingInstruction *iface,
636 BSTR p, IXMLDOMNode** outNode)
638 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
639 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode);
640 return node_select_singlenode(&This->node, p, outNode);
643 static HRESULT WINAPI dom_pi_get_parsed(
644 IXMLDOMProcessingInstruction *iface,
645 VARIANT_BOOL* isParsed)
647 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
648 FIXME("(%p)->(%p) stub!\n", This, isParsed);
649 *isParsed = VARIANT_TRUE;
650 return S_OK;
653 static HRESULT WINAPI dom_pi_get_namespaceURI(
654 IXMLDOMProcessingInstruction *iface,
655 BSTR* p)
657 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
658 TRACE("(%p)->(%p)\n", This, p);
659 return node_get_namespaceURI(&This->node, p);
662 static HRESULT WINAPI dom_pi_get_prefix(
663 IXMLDOMProcessingInstruction *iface,
664 BSTR* prefix)
666 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
667 TRACE("(%p)->(%p)\n", This, prefix);
668 return return_null_bstr( prefix );
671 static HRESULT WINAPI dom_pi_get_baseName(
672 IXMLDOMProcessingInstruction *iface,
673 BSTR* name)
675 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
676 TRACE("(%p)->(%p)\n", This, name);
677 return node_get_base_name( &This->node, name );
680 static HRESULT WINAPI dom_pi_transformNodeToObject(
681 IXMLDOMProcessingInstruction *iface,
682 IXMLDOMNode* domNode, VARIANT var1)
684 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
685 FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1));
686 return E_NOTIMPL;
689 static HRESULT WINAPI dom_pi_get_target(
690 IXMLDOMProcessingInstruction *iface,
691 BSTR *p)
693 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
695 TRACE("(%p)->(%p)\n", This, p);
697 /* target returns the same value as nodeName property */
698 return node_get_nodeName(&This->node, p);
701 static HRESULT WINAPI dom_pi_get_data(
702 IXMLDOMProcessingInstruction *iface,
703 BSTR *p)
705 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
706 HRESULT hr;
707 VARIANT ret;
709 TRACE("(%p)->(%p)\n", This, p);
711 if(!p)
712 return E_INVALIDARG;
714 hr = IXMLDOMProcessingInstruction_get_nodeValue( iface, &ret );
715 if(hr == S_OK)
717 *p = V_BSTR(&ret);
720 return hr;
723 static HRESULT WINAPI dom_pi_put_data(
724 IXMLDOMProcessingInstruction *iface,
725 BSTR data)
727 dom_pi *This = impl_from_IXMLDOMProcessingInstruction( iface );
728 BSTR target;
729 HRESULT hr;
731 TRACE("(%p)->(%s)\n", This, debugstr_w(data) );
733 /* cannot set data to a PI node whose target is 'xml' */
734 hr = IXMLDOMProcessingInstruction_get_nodeName(iface, &target);
735 if(hr == S_OK)
737 static const WCHAR xmlW[] = {'x','m','l',0};
738 if(!wcscmp(target, xmlW))
740 SysFreeString(target);
741 return E_FAIL;
744 SysFreeString(target);
747 return node_set_content(&This->node, data);
750 HRESULT dom_pi_put_xml_decl(IXMLDOMNode *node, BSTR data)
752 static const WCHAR xmlW[] = {'x','m','l',0};
753 xmlnode *node_obj;
754 HRESULT hr;
755 BSTR name;
757 if (!data)
758 return XML_E_XMLDECLSYNTAX;
760 node_obj = get_node_obj(node);
761 hr = node_set_content(node_obj, data);
762 if (FAILED(hr))
763 return hr;
765 hr = node_get_nodeName(node_obj, &name);
766 if (FAILED(hr))
767 return hr;
769 if (!lstrcmpW(name, xmlW) && !node_obj->node->properties)
770 hr = parse_xml_decl(node_obj->node);
771 else
772 hr = S_OK;
774 SysFreeString(name);
775 return hr;
778 static const struct IXMLDOMProcessingInstructionVtbl dom_pi_vtbl =
780 dom_pi_QueryInterface,
781 dom_pi_AddRef,
782 dom_pi_Release,
783 dom_pi_GetTypeInfoCount,
784 dom_pi_GetTypeInfo,
785 dom_pi_GetIDsOfNames,
786 dom_pi_Invoke,
787 dom_pi_get_nodeName,
788 dom_pi_get_nodeValue,
789 dom_pi_put_nodeValue,
790 dom_pi_get_nodeType,
791 dom_pi_get_parentNode,
792 dom_pi_get_childNodes,
793 dom_pi_get_firstChild,
794 dom_pi_get_lastChild,
795 dom_pi_get_previousSibling,
796 dom_pi_get_nextSibling,
797 dom_pi_get_attributes,
798 dom_pi_insertBefore,
799 dom_pi_replaceChild,
800 dom_pi_removeChild,
801 dom_pi_appendChild,
802 dom_pi_hasChildNodes,
803 dom_pi_get_ownerDocument,
804 dom_pi_cloneNode,
805 dom_pi_get_nodeTypeString,
806 dom_pi_get_text,
807 dom_pi_put_text,
808 dom_pi_get_specified,
809 dom_pi_get_definition,
810 dom_pi_get_nodeTypedValue,
811 dom_pi_put_nodeTypedValue,
812 dom_pi_get_dataType,
813 dom_pi_put_dataType,
814 dom_pi_get_xml,
815 dom_pi_transformNode,
816 dom_pi_selectNodes,
817 dom_pi_selectSingleNode,
818 dom_pi_get_parsed,
819 dom_pi_get_namespaceURI,
820 dom_pi_get_prefix,
821 dom_pi_get_baseName,
822 dom_pi_transformNodeToObject,
824 dom_pi_get_target,
825 dom_pi_get_data,
826 dom_pi_put_data
829 static xmlAttrPtr node_has_prop(const xmlNode *node, const xmlChar *name)
831 xmlAttrPtr prop;
833 /* xmlHasNsProp accepts only nodes of type XML_ELEMENT_NODE,
834 * so we have to look for an attribute in the node by hand.
837 prop = node->properties;
839 while (prop)
841 if (xmlStrEqual(prop->name, name))
842 return prop;
844 prop = prop->next;
847 return NULL;
850 static HRESULT dom_pi_get_qualified_item(const xmlNodePtr node, BSTR name, BSTR uri,
851 IXMLDOMNode **item)
853 FIXME("(%p)->(%s %s %p): stub\n", node, debugstr_w(name), debugstr_w(uri), item);
854 return E_NOTIMPL;
857 static HRESULT dom_pi_get_named_item(const xmlNodePtr node, BSTR name, IXMLDOMNode **item)
859 xmlChar *nameA;
860 xmlAttrPtr attr;
862 TRACE("(%p)->(%s %p)\n", node, debugstr_w(name), item);
864 if (!item) return E_POINTER;
866 nameA = xmlchar_from_wchar(name);
867 if (!nameA) return E_OUTOFMEMORY;
869 attr = node_has_prop(node, nameA);
870 heap_free(nameA);
872 if (!attr)
874 *item = NULL;
875 return S_FALSE;
878 *item = create_node((xmlNodePtr)attr);
880 return S_OK;
883 static HRESULT dom_pi_set_named_item(xmlNodePtr node, IXMLDOMNode *newItem, IXMLDOMNode **namedItem)
885 FIXME("(%p)->(%p %p): stub\n", node, newItem, namedItem );
886 return E_NOTIMPL;
889 static HRESULT dom_pi_remove_qualified_item(xmlNodePtr node, BSTR name, BSTR uri, IXMLDOMNode **item)
891 FIXME("(%p)->(%s %s %p): stub\n", node, debugstr_w(name), debugstr_w(uri), item);
892 return E_NOTIMPL;
895 static HRESULT dom_pi_remove_named_item(xmlNodePtr node, BSTR name, IXMLDOMNode **item)
897 FIXME("(%p)->(%s %p): stub\n", node, debugstr_w(name), item);
898 return E_NOTIMPL;
901 static HRESULT dom_pi_get_item(const xmlNodePtr node, LONG index, IXMLDOMNode **item)
903 FIXME("%p, %ld, %p: stub\n", node, index, item);
904 return E_NOTIMPL;
907 static HRESULT dom_pi_get_length(const xmlNodePtr node, LONG *length)
909 FIXME("(%p)->(%p): stub\n", node, length);
911 *length = 0;
912 return S_OK;
915 static HRESULT dom_pi_next_node(const xmlNodePtr node, LONG *iter, IXMLDOMNode **nextNode)
917 FIXME("%p, %ld, %p: stub\n", node, *iter, nextNode);
918 return E_NOTIMPL;
921 static const struct nodemap_funcs dom_pi_attr_map = {
922 dom_pi_get_named_item,
923 dom_pi_set_named_item,
924 dom_pi_remove_named_item,
925 dom_pi_get_item,
926 dom_pi_get_length,
927 dom_pi_get_qualified_item,
928 dom_pi_remove_qualified_item,
929 dom_pi_next_node
932 static const tid_t dompi_iface_tids[] = {
933 IXMLDOMProcessingInstruction_tid,
937 static dispex_static_data_t dompi_dispex = {
938 NULL,
939 IXMLDOMProcessingInstruction_tid,
940 NULL,
941 dompi_iface_tids
944 IUnknown* create_pi( xmlNodePtr pi )
946 dom_pi *This;
948 This = heap_alloc( sizeof *This );
949 if ( !This )
950 return NULL;
952 This->IXMLDOMProcessingInstruction_iface.lpVtbl = &dom_pi_vtbl;
953 This->ref = 1;
955 init_xmlnode(&This->node, pi, (IXMLDOMNode*)&This->IXMLDOMProcessingInstruction_iface, &dompi_dispex);
957 return (IUnknown*)&This->IXMLDOMProcessingInstruction_iface;